在Mozilla开发人员中心,有一个关于Function.prototype.bind
功能的页面,并为不支持此功能的浏览器提供兼容性功能。
但是,在分析此兼容性代码时,我无法找出他们使用instanceof nop
的原因。 nop
已设置为function() {}
。这与bind
的ECMA规范的哪一部分相符?什么变量是function() {}
的实例?
以下内容返回false
,因此我不完全知道它的用途。在进行instanceof function() {}
检查时会发生什么事情?
(function() {}) instanceof (function() {}) // false
代码如下:
Function.prototype.bind = function( obj ) {
if(typeof this !== 'function')
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
var slice = [].slice,
args = slice.call(arguments, 1),
self = this,
nop = function () {},
bound = function () {
return self.apply( this instanceof nop ? this : ( obj || {} ),
args.concat( slice.call(arguments) ) );
};
bound.prototype = this.prototype;
return bound;
};
答案 0 :(得分:8)
有人编辑了使其有用的部分。以下是它过去的样子:
Function.prototype.bind = function( obj ) {
var slice = [].slice,
args = slice.call(arguments, 1),
self = this,
nop = function () {},
bound = function () {
return self.apply( this instanceof nop ? this : ( obj || {} ),
args.concat( slice.call(arguments) ) );
};
// These lines are the important part
nop.prototype = self.prototype;
bound.prototype = new nop();
return bound;
};
我在这里回答了另一个问题(但代码是正确的):mozilla's bind function question。
this instanceof nop
检查的原因是,如果将绑定函数作为构造函数调用(即使用new
运算符),则this
绑定到新对象而不是无论你传递给bind
。
为了解释“重要部分”,nop
基本上被插入到原型链中,以便当您将该函数作为构造函数调用时,this
是一个实例nop
。
因此,如果您运行var bound = original.bind(someObject);
,原型链将如下所示:
original | nop | bound
我猜他们使用nop
而不是this instanceof self
的原因是为了使绑定函数拥有自己的prototype
属性(继承自self
)。有可能它不应该是为什么它被部分编辑出来的原因。无论如何,现在的代码是不正确的,但只要您不将该函数用作构造函数,它就会起作用。
答案 1 :(得分:3)
该实现似乎有错误。永远不会使用nop
(实例化任何东西)对instanceof
检查的期望,对于任何事情都不可能是真的,因为没有对象可以从nop
实例化,而// Identical definition, but different Function instances
var nop = function () {},
mop = function () {};
var obj1 = new mop;
obj1 instanceof mop // true
obj1 instanceof nop // false
深埋在该闭包中
考虑一下:
{{1}}