它允许您将绑定函数作为构造函数调用,而无需绑定到原始对象。换句话说,如果您使用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函数的用武之地。它本质上充当一个中间“类”,因此boundextends nopwhich 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.prototypeand bound.prototype = new nop(),创建的任何对象new bound()都将使用来自selfvia的原始原型创建bound.prototype。因此,函数调用里面,this instanceof nop(即Object.getPrototypeOf(NOP)== nop.prototype)是true和self被调用this(新创建的对象)。
在正常的函数调用中,'bound()'(没有new)this instanceof nop将是假的,因此obj作为this上下文传递,这就是您对绑定函数的期望。
使用中间函数的原因是为了避免调用原始函数(在 行中bound.prototype = new nop();),这可能会产生副作用。