解释Javascript的Function.prototype.bind浏览器垫片

时间:2014-12-10 21:38:30

标签: javascript this bind partial-application

我只是想了解以下来自MDN的代码。它是Function.prototype.bind的垫片:

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

首先,为什么aArgs最初会忽略参数列表中的第一个参数?

其次,为什么fToBind采用aArgs数组并将其余的参数连接起来?这不会创建一个args 1到n与args 0到n连接的数组吗?

我很困惑!

1 个答案:

答案 0 :(得分:3)

  

首先,为什么aArgs最初会忽略参数列表中的第一个参数?

因为第一个参数是this将设置为(oThis)的值。我们不希望稍后将其作为参数传递给函数。

  

其次,为什么fToBind采用aArgs数组并将其余的参数连接起来?这不会创建一个数组,其中args 1到n与args 0连接到n?

是。请注意,这些是不同的参数集。 aArgs是指传递给.bind()的参数,而arguments是指绑定函数 fBound的参数。

我们希望传递已传递给.bind的参数和已传递给绑定函数的参数。即我们想要

var fBound = f.bind(null, a, b); // aArgs = [a, b];
fBound(c, d); // arguments = [c, d]

等同于f(a, b, c, d)


基本上它会做所有事情,以便垫片像.bind一样有效。如果您对实施感到困惑,可能需要花费更多时间来更好地理解.bind