var counter =0; // Частное значение для функции ниже
return function() { return counter++; };
}());
Внимательно изучите этот пример, чтобы понять, как он действует. На первый взгляд, первая строка выглядит как инструкция присваивания функции переменной uniquelnteger. Фактически же это определение и вызов функции (как подсказывает открывающая круглая скобка в первой строке), поэтому в действительности переменной uniquelnteger присваивается значение, возвращаемое функцией. Если теперь обратить внимание на тело функции, можно увидеть, что она возвращает другую функцию. Именно этот объект вложенной функции и присваивается переменной uniquelnteger. Вложенная функция имеет доступ к переменным в ее области видимости и может использовать переменную counter, объявленную во внешней функции. После возврата из внешней функции никакой другой программный код не будет иметь доступа к переменной counter: вложенная функция будет обладать исключительным правом доступа к ней.
Скрытые переменные, такие как counter, не являются исключительной собственностью единственного замыкания: в одной и той же внешней функции вполне возможно определить две или более вложенных функций, которые будут совместно использовать одну цепочку областей видимости. Рассмотрим следующий пример:
function counter() { var n = 0;
return {
count: function() { return n++; },
reset: function() { n = 0; }
};
}
var c = counter(), d = counter(); // Создать два счетчика
c.count() // => 0
d.count() // => 0: они действуют независимо
с.reset() // методы reset() и count() совместно
// используют одну переменную
c.count() // => 0: сброс счетчика с
d.count() // => 1: не оказывает влияния на счетчик d
Функция counter() возвращает объект «счетчика». Этот объект имеет два метода: count(), возвращающий следующее целое число, и reset(), сбрасывающий счетчик в начальное состояние. В первую очередь следует запомнить, что два метода совместно используют одну и ту же частную переменную n. Во-вторых, каждый вызов функции counter() создает новую цепочку областей видимости и новую скрытую переменную. То есть, если вызвать функцию counter() дважды, она вернет два объекта-счетчика с различными скрытыми переменными. Вызов методов count() и reset() одного объекта-счетчика не оказывает влияния на другой.
Важно отметить, что описанный прием образования замыканий можно использовать в комбинации с приемом определения свойств с методами доступа. Следующая версия функции counter() является вариацией примера, представленного в разделе 6.6, но здесь для хранения скрытой информации вместо обычного свойства объекта используются замыкания:
function counter(n) { // Аргумент n функции - скрытая переменная
return {
// Метод чтения свойства возвращает и увеличивает переменную счетчика,
get count() { return n++; },
// Метод записи в свойство не позволяет уменьшать значение n
set count(m) {
if (m >= n)
n = m;
else throw Error( "значение счетчика нельзя уменьшить");
}
};
}
var с = counter(1000);