有一个关于我在Mozilla网站上找到的bind函数实现的问题。在大多数情况下,这对我来说很有意义,但我无法弄清楚这项检查的目的是什么......
this instanceof nop ? this : ( obj || {} )
在bind函数中。显然它检查'this'是否为空函数,但为什么需要绑定空函数。我在firebug中试过它,它有效,但重点是什么?只是想增加我的javascript知识,所以任何帮助将不胜感激。
if ( !Function.prototype.bind ) {
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) ) );
};
nop.prototype = self.prototype;
bound.prototype = new nop();
return bound;
};
}
答案 0 :(得分:28)
它允许您将绑定函数作为构造函数调用,而不必绑定到原始对象。换句话说,如果用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
返回的函数的行为会有所不同,具体取决于您是将其用作函数还是构造函数(请参阅ECMAScript 5语言规范的Section 15.3.4.5.1和15.3.4.5.2)。主要区别在于,当它被称为构造函数时,它会忽略“bound this”参数(因为在构造函数中,this
需要是新创建的对象)。因此bound
函数需要一种方法来确定它的调用方式。例如,bound(123)
与new bound(123)
相对应,并相应地设置this
。
这就是nop
函数的用武之地。它基本上充当了一个中间“类”,以便bound
扩展nop
扩展self
(这是函数{ {1}}被召唤)。那部分是在这里设置的:
bind()
调用bound函数时,它返回以下表达式:
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
(即Object.getPrototypeOf(nop)== nop.prototype)是this instanceof nop
并且true
被self
调用(新创建的对象) )。
在正常的函数调用中,'bound()'(没有this
),new
将为false,因此this instanceof nop
将作为obj
上下文传递,是你对绑定函数的期望。
使用中间函数的原因是为了避免调用可能有副作用的原始函数(在行this
中)。
答案 1 :(得分:0)
我认为这是(typeof obj != "undefined") ? obj : {}
也就是说,如果未定义obj
,则返回obj
,否则返回一个空对象({}是一个空对象)。