Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание
- Название:JavaScript. Подробное руководство, 6-е издание
- Автор:
- Жанр:
- Издательство:Символ-Плюс
- Год:2012
- Город:СПб
- ISBN:978-5-93286-215-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Флэнаган - JavaScript. Подробное руководство, 6-е издание краткое содержание
Эта книга - одновременно и руководство программиста, и полноценный справочник по базовому языку JavaScript и клиентским прикладным интерфейсам, предоставляемым веб-броузерами.
JavaScript. Подробное руководство, 6-е издание - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
// Замещает метод m объекта о версией метода, которая регистрирует
// сообщения до и после вызова оригинального метода.
function trace(o, m) {
var original = o[m]; // Сохранить оригинальный метод в замыкании.
o[m] = function() { // Определить новый метод.
console.log(new Date(), "Entering:", m); // Записать сообщение,
var result = original.apply(this, arguments): // Вызвать оригинал,
console.log(new Date(), "Exiting:", m); // Записать сообщение,
return result: // Вернуть результат.
};
}
Эта функция trace()
принимает объект и имя метода. Она замещает указанный метод новым методом, который «обертывает» оригинальный метод дополнительной функциональностью. Такой прием динамического изменения существующих методов иногда называется «обезьяньей заплатой» («monkey-patching»).
8.7.4. Метод bind()
Метод bind()
впервые появился в ECMAScript 5, но его легко имитировать в ЕСМА-Script 3. Как следует из его имени, основное назначение метода bind()
состоит в том, чтобы связать (bind) функцию с объектом. Если вызвать метод bind()
функции f и передать ему объект о, он вернет новую функцию. Вызов новой функции (как обычной функции) выполнит вызов оригинальной функции f как метода объекта о. Любые аргументы, переданные новой функции, будут переданы оригинальной функции. Например:
function f(у) { return this.x + у: } // Функция, которую требуется привязать
var о = { х : 1 }; // Объект, к которому выполняется привязка
var g = f.bind(o); // Вызов g(х) вызовет o.f(x)
g(2) // => 3
Такой способ связывания легко реализовать в ECMAScript 3, как показано ниже:
// Возвращает функцию, которая вызывает f как метод объекта о
// и передает ей все свои аргументы,
function bind(f, о) {
if (f.bind) return f.bind(o): // Использовать метод bind, если имеется
else return function() { // Иначе связать, как показано ниже
return f.apply(o, arguments):
};
}
Метод bind()
в ECMAScript 5 не просто связывает функцию с объектом. Он также выполняет частичное применение: помимо значения this
связаны будут все аргументы, переданные методу bind()
после первого его аргумента. Частичное применение - распространенный прием в функциональном программировании и иногда называется каррингом (currying). Ниже приводится несколько примеров использования метода bind()
для частичного применения:
var sum = function(x,у) { return х + у }; // Возвращает сумму 2 аргументов
// Создать новую функцию, подобную sum, но со связанным значением null
// ключевого слова this и со связанным значением первого аргумента, равным 1.
// Новая функция принимает всего один аргумент,
var succ = sum.bind(null, 1);
succ(2) // => 3: аргумент x связан со значением 1, а 2 передается в арг. у
function f(y.z) { return this.x + у + z }; // Еще одна функция сложения
var g = f.bind({x:1}, 2); // Связать this и у
g(3) // => 6: this.x - связан с 1, у - связан с 2, а 3 передается в z
В ECMAScript 3 также возможно связывать значение this
и выполнять частичное применение. Стандартный метод bind()
можно имитировать программным кодом, который приводится в примере 8.5. Обратите внимание, что этот метод сохраняется как Function.prototype.bind
, благодаря чему все функции наследуют его. Данный прием подробно рассматривается в разделе 9.4.
Пример 8.5. Метод Function.bind() для ECMAScript 3
if (!Function.prototype.bind) {
Function.prototype.bind = function(o /*, аргументы */) {
// Сохранить this и arguments в переменных, чтобы их можно было
// использовать во вложенной функции ниже,
var self = this, boundArgs = arguments;
// Возвращаемое значение метода bind() - функция
return function() {
// Сконструировать список аргументов, начиная со второго аргумента
// метода bind, и передать все эти аргументы указанной функции,
var args = [], і;
fог(і = 1; і < boundArgs.length; i++) args.push(boundArgs[i]);
for(i = 0; і < arguments.length; i++) args.push(arguments[i]);
// Теперь вызвать self как метод объекта о со всеми аргументами
return self.apply(о, args);
};
};
}
Обратите внимание, что функция, возвращаемая этим методом bind(),
является замыканием, использующим переменные self
и boundArgs,
объявленные во внешней функции, которые остаются доступными вложенной функции даже после того, как она будет возвращена внешней функцией и вызвана из-за пределов внешней функции.
Метод bind(),
определяемый стандартом ECMAScript 5, имеет некоторые особенности, которые невозможно реализовать в ECMAScript 3. Прежде всего, настоящий метод bind()
возвращает объект функции, свойство length
которой установлено в соответствии с количеством параметров связываемой функции, минус количество связанных аргументов (но не меньше нуля). Во-вторых, метод bind(
) в ECMAScript 5 может использоваться для частичного применения функций-конструкторов. Если функцию, возвращаемую методом bind(),
использовать как конструктор, значение this
, переданное методу bind(),
игнорируется, и оригинальная функция будет вызвана как конструктор, с уже связанными аргументами, если они были определены. Функции, возвращаемые методом bind(),
не имеют свойства prototype (свойство prototype обычных функций нельзя удалить), и объекты, созданные связанными функциями-конструкторами, наследуют свойство prototype оригинального, несвязанного конструктора. Кроме того, с точки зрения оператора instanceof
связанные конструкторы действуют точно так же, как несвязанные конструкторы.
8.7.5. Метод toString()
Подобно другим объектам в языке JavaScript, функции имеют метод toString()
. Спецификация ECMAScript требует, чтобы этот метод возвращал строку, следующую синтаксису инструкции объявления функции. На практике большинство (но не все) реализаций метода toString()
возвращают полный исходный текст функции. Для встроенных функций обычно возвращается строка, содержащая вместо тела функции текст «[native code]» или аналогичный.
8.7.6. Конструктор Function()
Интервал:
Закладка: