Чтение онлайн

ЖАНРЫ

JavaScript. Подробное руководство, 6-е издание
Шрифт:

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 замыканий будут совместно использовать это значение. Таким образом, все функции в возвращаемом массиве будут возвращать одно и то же значение, что совсем не то, чего мы пытались добиться. Важно помнить, что цепочка областей видимости, связанная с замыканием, не фиксируется. Вложенные функции не создают частные копии области видимости и не фиксируют значения переменных.

Кроме того, при создании замыканий следует помнить, что

this
– это ключевое слово, а не переменная. Как отмечалось выше, каждый вызов функции получает свое значение
this
, и замыкание не имеет доступа к значению
this
внешней функции, если внешняя функция не сохранит его в переменной:

var self = this; // Сохранить значение this в переменной для использования

// во вложенной функции.

То же относится и к объекту

arguments
. Это не ключевое слово, но он автоматически создается при каждом вызове функции. Поскольку замыкания при вызове получают собственный объект
arguments
, они не могут обращаться к массиву аргументов внешней функции, если внешняя функция не сохранит этот массив в переменной с другим именем:

var outerArguments = arguments; // Сохранить для использования во вложенных функциях

В примере 8.5, далее в этой главе, определяется замыкание, использующее эти приемы для получения доступа к значениям

this
и
arguments
внешней функции.

8.7. Свойства и методы функций и конструктор Function

Мы видели, что в JavaScript-программах функции могут использоваться как значения. Оператор

typeOf
возвращает для функций строку «function», однако в действительности функции в языке JavaScript - это особого рода объекты. А раз функции являются объектами, то они имеют свойства и методы, как любые другие объекты. Существует даже конструктор
Function,
который создает новые объекты функций. В следующих подразделах описываются свойства и методы функций, а также конструктор
Function.
Кроме того, информация обо всем этом приводится в справочном разделе.

8.7.1. Свойство length

В теле функции свойство

arguments.length
определяет количество аргументов, переданных функции. Однако свойство
length
самой функции имеет иной смысл. Это свойство, доступное только для чтения, возвращает количество аргументов, которое функция ожидает получить, - число объявленных параметров.

В следующем фрагменте определяется функция с именем

check,
получающая массив аргументов
arguments
от другой функции. Она сравнивает свойство
arguments.length
(число фактически переданных аргументов) со свойством
arguments. callee.length
(число ожидаемых аргументов), чтобы определить, передано ли функции столько аргументов, сколько она ожидает. Если значения не совпадают, генерируется исключение. За функцией
check
следует тестовая функция
f
, демонстрирующая порядок использования функции
check:

// Эта функция использует arguments.callee, поэтому она

// не будет работать в строгом режиме,

function check(args) {

var actual = args.length; // Фактическое число аргументов

var expected = args.callee.length; // Ожидаемое число аргументов

if (actual !== expected) // Если не совпадают, генерируется исключение

Поделиться с друзьями: