Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript mozilla';s-约束函数问题_Javascript - Fatal编程技术网

Javascript mozilla';s-约束函数问题

Javascript mozilla';s-约束函数问题,javascript,Javascript,我在Mozilla的网站上发现了一个关于bind函数实现的问题。在大多数情况下,这对我来说是有意义的,但我不知道这张支票是用来做什么的 this instanceof nop ? this : ( obj || {} ) 在bind函数中。显然,它会检查'this'是否是空函数,但是为什么需要绑定空函数呢。我在firebug中尝试过,它很有效,但有什么意义呢?我只是想增加我的javascript知识,希望能得到您的帮助 if ( !Function.prototype.bind ) {

我在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;
  };
}

我认为这是
(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()的解释函数可以工作。希望它至少有一点意义。@TinaChen
bind
函数不能调用
new self()
,因为这会调用函数,这可能会产生副作用。例如,如果您有以下函数:
function f(){alert('oops');}
,则
f.bind({})会令人惊讶(而且不正确))
显示警报。
nop
函数在
bind
中定义,不做任何事情,因此可以安全调用。