Javascript mozilla';s-约束函数问题
我在Mozilla的网站上发现了一个关于bind函数实现的问题。在大多数情况下,这对我来说是有意义的,但我不知道这张支票是用来做什么的Javascript mozilla';s-约束函数问题,javascript,Javascript,我在Mozilla的网站上发现了一个关于bind函数实现的问题。在大多数情况下,这对我来说是有意义的,但我不知道这张支票是用来做什么的 this instanceof nop ? this : ( obj || {} ) 在bind函数中。显然,它会检查'this'是否是空函数,但是为什么需要绑定空函数呢。我在firebug中尝试过,它很有效,但有什么意义呢?我只是想增加我的javascript知识,希望能得到您的帮助 if ( !Function.prototype.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;
};
}
我认为这是
(typeof obj!=“undefined”)的一个简短符号?obj:{}
也就是说,如果未定义
obj
,则返回obj
,否则返回空对象({}是空对象)。Its允许您将绑定函数作为构造函数调用,而无需绑定到原始对象。换句话说,“绑定”函数仍然可以像原始的未绑定版本一样工作,如果您使用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语言规范的和)。主要区别在于,当作为构造函数调用时,它会忽略“boundthis”参数(因为在构造函数中,this
需要是新创建的对象)。因此,bound
函数需要一种方法来确定如何调用它。例如,bound(123)
vs.newbound(123)
并相应地设置this
这就是nop
函数的作用。它本质上是一个中间“类”,因此bind
扩展了nop
,它扩展了self
(调用了bind()
函数)。该部分设置在此处:
nop.prototype = self.prototype;
bound.prototype = new nop();
调用绑定函数时,它返回以下表达式:
self.apply( this instanceof nop ? this : obj, arguments ) )
nop的此实例通过遵循原型链来确定该的任何原型是否等于nop.prototype
。通过设置nop.prototype=self.prototype
和bound.prototype=new nop()
,使用new bound()
创建的任何对象都将通过bound.prototype
从self
使用原始原型创建。因此,在函数调用中,nop的这个实例(即Object.getPrototypeOf(nop)==nop.prototype)是true
,self
被this
调用(新创建的对象)
在正常函数调用“bound()”(不带new
)中,nop
的此实例将为false,因此obj
将作为此
上下文传递,这是您在绑定函数上所期望的
使用中间函数的原因是为了避免调用原始函数(在bound.prototype=new nop();
行中),这可能会产生副作用。hmm-不确定我是否只是不完全理解您的答案,因为我当然不是javascript专家,但让我停顿的部分是“这是nop的例子?this“似乎表示如果“this”是空函数,那么返回“this”-这意味着我们正在将空函数绑定到(obj | |{})这一部分很清楚。让人困惑的是“nop”部分。对不起,你是对的,我快速阅读了一遍,没有抓住要点,让我再读一遍:)弹出js控制台并对其进行评估,看看你得到了什么!这真的让人困惑。因为它在调用自己,它可能会使用它来防止无限循环?或者它可能只是为了性能?是的-我知道我试过了-它可以工作,但是我绑定到空函数,所以什么也没有发生。我只是想知道是否有人知道我为什么会这样做,或者为什么它是这样写的。为什么它会拆分参数,然后再对它们进行concat?有这么快吗?我会猜参数。concat([]))是最快的克隆方法。参数第一次被拆分,因为如果您执行类似操作--function.bind obj arg1 arg2-您将得到一个绑定到已填充arg1和arg2的对象的函数-函数的部分应用程序--然后当您使用args调用实际绑定函数时,这些函数是concate使用你最初绑定函数的参数——至少这是我能做的最好的解释——非常有趣而且看起来正确——我从来没有想到过——不知何故,我不明白上面的nop
是如何影响这个答案的。@SunnyRGupta我想我回答了它的作用,但没有解释它是如何作用的ally的工作原理。它对javascript的工作原理有相当深入的了解,但我会看看是否可以解释它。@SunnyRGupta我不记得编辑答案时是否会通知您,但我添加了一些关于nop()的解释函数可以工作。希望它至少有一点意义。@TinaChenbind
函数不能调用new self()
,因为这会调用函数,这可能会产生副作用。例如,如果您有以下函数:function f(){alert('oops');}
,则f.bind({})会令人惊讶(而且不正确))
显示警报。nop
函数在bind
中定义,不做任何事情,因此可以安全调用。