Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание
- Название:JavaScript. Подробное руководство, 6-е издание
- Автор:
- Жанр:
- Издательство:Символ-Плюс
- Год:2012
- Город:СПб
- ISBN:978-5-93286-215-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание краткое содержание
Эта книга - одновременно и руководство программиста, и полноценный справочник по базовому языку JavaScript и клиентским прикладным интерфейсам, предоставляемым веб-броузерами.
JavaScript. Подробное руководство, 6-е издание - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
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) {
var value; // Это значение свойства
// Метод чтения просто возвращает значение.
о["get" + name] = function() { return value; };
// Метод записи сохраняет значение или возбуждает исключение,
// если функция проверки отвергает это значение.
o["set" + name] = function(v) {
if (predicate && !predicate(v))
throw Error("set" + name + недопустимое значение + v);
else
value = v;
};
}
// Следующий фрагмент демонстрирует работу метода addPrivateProperty().
var о = {}; // Пустой объект
// Добавить к свойству методы доступа с именами getName() и setName()
// Обеспечить допустимость только строковых значений
addPrivateProperty(o, "Name", function(x) { return typeof x == "string"; });
o.setName("Frank"); // Установить значение свойства
console.log(o.getName()); // Получить значение свойства
о.setName(0); // Попробовать установить значение свойства неверного типа
Мы увидели несколько примеров, когда замыкания определяются в одной и той же цепочке областей видимости и совместно используют одну локальную пере¬менную или переменные. Важно знать и уметь пользоваться этим приемом, но но менее важно уметь распознавать ситуации, когда замыкания получают перемен¬ную в совместное использование по ошибке. Рассмотрим следующий пример:
// Эта функция возвращает функцию, которая всегда возвращает v
function constfunc(v) { return function() { return v; }; }
// Создать массив функций-констант:
var funcs = [];
for(var і = 0; і < 10; i++) funcs[i] = constfunc(i);
// Функция в элементе массива с индексом 5 возвращает 5.
funcs[5]() // => 5
При создании подобного программного кода, который создает множество замыканий в цикле, часто допускают ошибку, помещая цикл внутрь функции, которая определяет замыкания. Например, взгляните на следующий фрагмент:
// Возвращает массив функций, возвращающих значения 0-9
function constfuncs() { var funcs = [];
for(var і = 0; і < 10; i++)
funcs[i] = function() { return i; };
return funcs;
}
var funcs = constfuncs();
funcs[5]() // Что вернет этот вызов?
Функция выше создает 10 замыканий и сохраняет их в массиве. Замыкания образуются в одном и том же вызове функции, поэтому все они получат доступ к переменной і. Когда constfuncs()
вернет управление, переменная і будет иметь значение 10, и все 10 замыканий будут совместно использовать это значение. Таким образом, все функции в возвращаемом массиве будут возвращать одно и то же значение, что совсем не то, чего мы пытались добиться. Важно помнить, что цепочка областей видимости, связанная с замыканием, не фиксируется. Вложенные функции не создают частные копии области видимости и не фиксируют значения переменных.
Интервал:
Закладка: