它允许您将绑定函数作为构造函数调用,而无需绑定到原始对象。换句话说,如果您使用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语言规范)。主要区别在于它在作为构造函数调用时忽略“绑定 this”参数(因为在构造函数内部,this
需要是新创建的对象)。因此该bound
函数需要一种方法来确定它是如何被调用的。例如,bound(123)
vs.new bound(123)
并相应地设置this
。
这就是nop
函数的用武之地。它本质上充当一个中间“类”,因此bound
extends nop
which extends 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
and bound.prototype = new nop()
,创建的任何对象new bound()
都将使用来自self
via的原始原型创建bound.prototype
。因此,函数调用里面,this instanceof nop
(即Object.getPrototypeOf(NOP)== nop.prototype)是true
和self
被调用this
(新创建的对象)。
在正常的函数调用中,'bound()'(没有new
)this instanceof nop
将是假的,因此obj
作为this
上下文传递,这就是您对绑定函数的期望。
使用中间函数的原因是为了避免调用原始函数(在 行中bound.prototype = new nop();
),这可能会产生副作用。