Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание
- Название:JavaScript. Подробное руководство, 6-е издание
- Автор:
- Жанр:
- Издательство:Символ-Плюс
- Год:2012
- Город:СПб
- ISBN:978-5-93286-215-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание краткое содержание
Эта книга - одновременно и руководство программиста, и полноценный справочник по базовому языку JavaScript и клиентским прикладным интерфейсам, предоставляемым веб-броузерами.
JavaScript. Подробное руководство, 6-е издание - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Кроме того, при создании замыканий следует помнить, что 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) // Если не совпадают, генерируется исключение
throw new Еrror("ожидается: " + expected + получено " + actual);
}
function f(x, у, z) {
// Проверить число ожидаемых и фактически переданных аргументов.
check(arguments);
// Теперь выполнить оставшуюся часть функции как обычно
return х + у + z;
}
8.7.2. Свойство prototype
Любая функция имеет свойство prototype, ссылающееся на объект, известный как объект прототипа. Каждая функция имеет свой объект прототипа. Когда функция используется в роли конструктора, вновь созданный объект наследует свойства этого объекта прототипа. Прототипы и свойство prototype обсуждались в разделе 6.1.3, и мы еще раз вернемся к этим понятиям в главе 9.
8.7.3. Методы call() и apply()
Методы саll()
и аррlу()
позволяют выполнять косвенный вызов функции (раздел 8.2.4), как если бы она была методом некоторого другого объекта. (Мы уже использовали метод саll()
в примере 6.4 для вызова Object.prototype.toString
относительно объекта, класс которого необходимо было определить.) Первым аргументом обоим методам, саll()
и аррlу(),
передается объект, относительно которого вызывается функция; этот аргумент определяет контекст вызова и становится значением ключевого слова this
в теле функции. Чтобы вызвать функцию f()
(без аргументов) как метод объекта о, можно использовать любой из методов, саll()
или аррlу():
f.call(о);
f.apply(o);
Любой из этих способов вызова эквивалентен следующему фрагменту (где предполагается, что объект о не имеет свойства с именем m):
о.m = f; // Временно сделать f методом о.
о.m(); // Вызывать его без аргументов,
delete о.m; // Удалить временный метод.
В строгом режиме ECMAScript 5 первый аргумент методов саll()
и apply()
становится значением this
, даже если это простое значение, null
или undefined
. В ECMAScript 3 и в нестрогом режиме значения null
и undefined
замещаются глобальным объектом, а простое значение - соответствующим объектом-оберткой.
Все остальные аргументы метода саll(),
следующие за первым аргументом, определяющим контекст вызова, передаются вызываемой функции. Например, ниже показано, как можно передать функции f()
два числа и вызвать ее, как если бы она была методом объекта о:
f.call(o, 1, 2);
Метод аррlу()
действует подобно методу саll(),
за исключением того, что аргументы для функции передаются в виде массива:
f.apply(o, [1,2]);
Если функция способна обрабатывать произвольное число аргументов, метод apply()
может использоваться для вызова такой функции в контексте массива произвольной длины. Например, чтобы отыскать наибольшее число в массиве чисел, для передачи элементов массива функции Math.max()
можно было бы использовать метод ар ply ():
var biggest = Math.max.apply(Math, array_of_numbers);
Обратите внимание, что метод apply()
может работать не только с настоящими массивами, но и с объектами, подобными массивам. В частности, вы можете вызвать функцию с теми же аргументами, что и текущую функцию, передав массив с аргументами непосредственно методу аррlу().
Этот прием демонстрируется ниже:
Интервал:
Закладка: