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

<b>// Замещает метод m объекта о версией метода, которая регистрирует </b>

<b>// сообщения до и после вызова оригинального метода.</b>

<b>function trace(o, m) {</b>

<b>  var original = o[m]; // Сохранить оригинальный метод в замыкании.</b>

<b>  o[m] = function() { // Определить новый метод.</b>

<b>    console.log(new Date(), &quot;Entering:&quot;, m); // Записать сообщение,</b>

<b>    var result = original.apply(this, arguments): // Вызвать оригинал, </b>

<b>    console.log(new Date(), &quot;Exiting:&quot;, m); // Записать сообщение,</b>

<b>    return result: // Вернуть результат.</b>

<b>  };</b>

<b>}</b>

Эта функция

<b>trace()</b>
принимает объект и имя метода. Она замещает указанный метод новым методом, который «обертывает» оригинальный метод дополнительной функциональностью. Такой прием динамического изменения существующих методов иногда называется «обезьяньей заплатой» («monkey-patching»).

8.7.4. Метод bind()

Метод

<b>bind()</b>
впервые появился в ECMAScript 5, но его легко имитировать в ЕСМА-Script 3. Как следует из его имени, основное назначение метода
<b>bind()</b>
состоит в том, чтобы связать (bind) функцию с объектом. Если вызвать метод
<b>bind()</b>
функции f и передать ему объект о, он вернет новую функцию. Вызов новой функции (как обычной функции) выполнит вызов оригинальной функции f как метода объекта о. Любые аргументы, переданные новой функции, будут переданы оригинальной функции. Например:

<b>function f(у) { return this.x + у: } // Функция, которую требуется привязать </b>

<b>var о = { х : 1 }; // Объект, к которому выполняется привязка</b>

<b>var g = f.bind(o); // Вызов g(х) вызовет o.f(x)</b>

<b>g(2) // =&gt; 3</b>

Такой способ связывания легко реализовать в ECMAScript 3, как показано ниже:

<b>// Возвращает функцию, которая вызывает f как метод объекта о </b>

<b>// и передает ей все свои аргументы, </b>

<b>function bind(f, о) {</b>

<b>   if (f.bind) return f.bind(o): // Использовать метод bind, если имеется</b>

<b>   else return function() { // Иначе связать, как показано ниже</b>

<b>            return f.apply(o, arguments):</b>

<b>  };</b>

<b>}</b>

Метод

<b>bind()</b>
в ECMAScript 5 не просто связывает функцию с объектом. Он также выполняет частичное применение: помимо значения
<b>this</b>
связаны будут все аргументы, переданные методу
<b>bind()</b>
после первого его аргумента. Частичное применение - распространенный прием в функциональном программировании и иногда называется каррингом (currying). Ниже приводится несколько примеров использования метода
<b>bind()</b>
для частичного применения:

<b>var sum = function(x,у) { return х + у }; // Возвращает сумму 2 аргументов</b>

<b>// Создать новую функцию, подобную sum, но со связанным значением null </b>

<b>// ключевого слова this и со связанным значением первого аргумента, равным 1.</b>

<b>// Новая функция принимает всего один аргумент, </b>

<b>var succ = sum.bind(null, 1);</b>

<b>succ(2) // =&gt; 3: аргумент x связан со значением 1, а 2 передается в арг. у</b>

<b>function f(y.z) { return this.x + у + z }; // Еще одна функция сложения</b>

<b>var g = f.bind({x:1}, 2); // Связать this и у</b>

<b>g(3)     // =&gt; 6: this.x - связан с 1, у - связан с 2, а 3 передается в z</b>

В ECMAScript 3 также возможно связывать значение

<b>this</b>
и выполнять частичное применение. Стандартный метод
<b>bind()</b>
можно имитировать программным кодом, который приводится в примере 8.5. Обратите внимание, что этот метод сохраняется как
<b>Function.prototype.bind</b>
, благодаря чему все функции наследуют его. Данный прием подробно рассматривается в разделе 9.4.

Пример 8.5. Метод Function.bind() для ECMAScript 3

<b>if (!Function.prototype.bind) {</b>

<b>Function.prototype.bind = function(o /*, аргументы */) {</b>

<b>    // Сохранить this и arguments в переменных, чтобы их можно было </b>

<b>    // использовать во вложенной функции ниже, </b>

<b>    var self = this, boundArgs = arguments;</b>

<b>    // Возвращаемое значение метода bind() - функция </b>

<b>    return function() {</b>

<b>      // Сконструировать список аргументов, начиная со второго аргумента </b>

<b>      // метода bind, и передать все эти аргументы указанной функции, </b>

<b>      var args = [], і;</b>

<b>      fог(і = 1; і &lt; boundArgs.length; i++) args.push(boundArgs[i]); </b>

<b>      for(i = 0; і &lt; arguments.length; i++) args.push(arguments[i]);</b>