Скрытые переменные, такие как 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);
с.count // => 1000
с.count // => 1001
с.count = 2000
с.count // => 2000
с.count = 2000 // => Ошибка!
Обратите внимание, что эта версия функции counter()
не объявляет локальную переменную. Для сохранения информации она просто использует параметр n, доступный обоим методам доступа к свойству. Это позволяет программе, вызывающей counter(),
определять начальное значение скрытой переменной.
В примере 8.4 демонстрируется обобщение приема совместного использования скрытой информации в замыканиях. Этот пример определяет функцию addPrivateProperty(), которая в свою очередь определяет скрытую переменную и две вложенные функции для чтения и записи значения этой переменной. Она добавляет эти вложенные функции как методы указанного вами объекта:
Пример 8.4. Реализация методов доступа к частному свойству с использованием замыканий
// Эта функция добавляет методы доступа к свойству с заданным именем объекта о.
// Методы получают имена вида get и set. Если дополнительно предоставляется
// функция проверки, метод записи будет использовать ее для проверки значения
// перед сохранением. Если функция проверки возвращает false,
// метод записи генерирует исключение.
//
// Необычность такого подхода заключается в том, что значение свойства,
// доступного методам, сохраняется не в виде свойства объекта о, а в виде
// локальной переменной этой функции. Кроме того, методы доступа также определяются
// внутри этой функции и потому получают доступ к этой локальной переменной.
// Это означает, что значение доступно только этим двум методам и не может быть
// установлено или изменено иначе, как методом записи,
function addPrivateProperty(o, name, predicate) {
Читать дальше
Конец ознакомительного отрывка
Купить книгу