Ответ 1
Его позволяет вызывать связанную функцию как конструктор без привязки к исходному объекту. Другими словами, функция "bound" будет работать так же, как и исходная, несвязанная версия, если вы вызываете ее с помощью new
.
Вот пример:
var obj = {};
function foo(x) {
this.answer = x;
}
var bar = foo.bind(obj); // "always" use obj for "this"
bar(42);
console.log(obj.answer); // 42
var other = new bar(1); // Call bar as a constructor
console.log(obj.answer); // Still 42
console.log(other.answer); // 1
Как это работает
Чтобы упростить объяснение, здесь приведена упрощенная версия кода, который связывает только this
и не обрабатывает аргументы или отсутствующий параметр obj:
Function.prototype.bind = function( obj ) {
var self = this,
nop = function () {},
bound = function () {
return self.apply( this instanceof nop ? this : obj, arguments );
};
nop.prototype = self.prototype;
bound.prototype = new nop();
return bound;
};
Функция, возвращаемая Function.prototype.bind
, ведет себя по-разному в зависимости от того, используете ли вы ее как функцию или конструктор (см. Раздел 15.3.4.5.1 и 15.3.4.5.2 спецификации языка ECMAScript 5). Основное отличие состоит в том, что он игнорирует параметр "bound this", когда он вызывается как конструктор (так как внутри конструктора this
должен быть вновь созданный объект). Таким образом, функция bound
должна определить способ ее вызова. Например, bound(123)
vs. new bound(123)
и установите this
соответственно.
То, в которое входит функция nop
. Она по существу действует как промежуточный "класс", так что bound
extends nop
, который продолжается self
(к которому была вызвана функция bind()
). Эта часть создана здесь:
nop.prototype = self.prototype;
bound.prototype = new nop();
Когда вы вызываете связанную функцию, она возвращает это выражение:
self.apply( this instanceof nop ? this : obj, arguments ) )
this instanceof nop
работает, следуя цепочке прототипов, чтобы определить, является ли какой-либо прототип this
равным nop.prototype
. Установив nop.prototype = self.prototype
и bound.prototype = new nop()
, любой объект, созданный с помощью new bound()
, будет создан с исходным прототипом от self
через bound.prototype
. Таким образом, внутри вызова функции this instanceof nop
(т.е. Object.getPrototypeOf(nop) == nop.prototype) есть true
и self
получает вызов с this
(вновь созданный объект).
В обычном вызове функции "bound()" (без new
), this instanceof nop
будет ложным, поэтому obj
передается как контекст this
, что и ожидалось бы на привязке функция.
Причина использования промежуточной функции заключается в том, чтобы избежать вызова исходной функции (в строке bound.prototype = new nop();
), которая может иметь побочные эффекты.