53. Замыкания.
Если функция F()
возвращает свою вложенную функцию g()
, то все переменные из scope F()
(и их значения) будут доступны в g()
. Это явление называется замыканием (closure).
function func(param) {
var clos = param;
function res(x) {
return x + clos;
}
return res;
}
var f1 = func(100);
alert(f1(10)); // "110"
var f2 = func(200);
alert(f2(10)); // "210"
function uniqueID() {
var counter = 0;
return function () {
return counter++;
}
}
var u1 = uniqueID();
alert(u1()); // 0
alert(u1()); // 1
var u2 = uniqueID();
alert(u2()); // 0
function counter() {
var n = 0;
return {
count: function () { return n++; },
reset: function () { n = 0; }
};
}
var c = counter(), d = counter(); // два счётчика
c.count() // => 0
c.count() // => 1
d.count() // => 0: действуют независимо
c.reset()
c.count() // => 0
В современном JavaScript распространён приём: объявляется выражение-функция (без имени) и сразу же происходит вызов этой функции:
Внешние скобки нужны, чтобы транслятор понимал это как выражение-функцию (если он может подумать, что это инструкция ☺).
(function() {
// тело функции
}());
(function() {
// тело функции
})();
Перепишем один из примеров для замыканий с использование данного приёма:
var uniqueID = (function() {
var counter = 0;
return function () {
return counter++;
}
}());
alert(uniqueID()); // 0
alert(uniqueID()); // 1
НВФ хороши тем, что дают изолированную область (по переменным), выполняемую один раз.
Это используют, например, в различных сценариях инициализации.
Или делают из НВФ подобие замкнутого модуля.