В javaScript используются лексические области видимости. Это означает, что при выполнении функций действуют области видимости переменных, которые имелись на момент их определения, а не на момент вызова.
var scope = “global”; function check(){ var scope = “local”; function f(){return scope} return f; } check()(); // вернет “local”
Рассмотрим следующий пример преобразования замыканий.
function counter(){ var n = 0; return { count: function(){return n++;} reset: function(){n=0;} }; } var c = counter(), d = counter; // создать два счетчика c.count(); // вернет 0 d.cound(); // вернет 0 c.reset(); // обнуление, вернет 0 c.count(); // вернет 0 d.count(); // вернет 1
Чтобы понять суть замыканий, требуется знать три основных факта:
1. JavaScript позволяет ссылаться на переменные, определенные за пределами текущей функции:
- ссылка на переменные определенные за пределами текущей функции.
2. Функции могут ссылаться на переменные, определенные во внешних функциях. Функции, отслеживающие переменные, в содержащих эти переменные областях видимости, и называются замыканиями.
- можно возвращать внутреннюю функцию для его последующего вызова. Функция make() является замыканием, код которого ссылается на две внешние переменные: magic и filling. Функция может ссылаться на люые переменные в своей области видимости.
Этим можно воспользоваться для создания более универсальной функции main().
function main(magic){ function make(filling){ return magic + " и " + filling; } return make; } var f = main("овощи"); f("фрукты"); //овощи и фрукты f("огород"); //овощи и огород var f = main("кофе"); f("чай"); //кофе и чай f("молоко"); //кофе и молоко
3. Замыкания хранят внутри себя ссылки на внешние переменные, они способны как читать, так и обновлять эти свои переменные.
function box(){ var val = undefined; return { set: function(newVal){val = newVal;}, get: function(){return val;}, type: function(){return typeof val;} }; } var b = box(); b.type(); //undefined b.set(98.6) b.get(); // 98.6 b.type(); // "number"
В этом примере создается объект, в котором содержится три замыкания – это его свойства: set (определение или переопределение переменной), get (вернуть переменную), type (определить тип переменной).