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