你能用`bind`重新绑定一个反弹函数吗?

Lor*_*lor 13 javascript

bindmethod创建一个新函数,调用时将其this关键字设置为提供的值.

var obj = {
  a: 0,
  b() {
    console.log(this.a);
  }
}

obj.b() // -> 0

var functionBound = obj.b.bind(obj)
functionBound() // -> 0
functionBound.bind(null)() // -> 0 AND I expect an error here
Run Code Online (Sandbox Code Playgroud)

显然,我无法重新绑定一个已经被反弹的功能.但是,我找不到有关此行为的任何文档.

自" 在Javascript中绑定已绑定函数的更多参数 "

将对象绑定到具有bind的函数后,就无法覆盖它.正如你在MDN文档中看到的那样,它清楚地写在规范中:

bind()函数创建一个新函数(一个绑定函数),它具有相同的函数体(ECMAScript 5术语中的内部调用属性)作为它被调用的函数(绑定函数的目标函数),该值绑定到bind()的第一个参数,它不能被覆盖.

我在MDN文档中找不到这些.我在Google上面的引文上做了一个精确的全文搜索,似乎上面的SO答案是这种行为的唯一来源.我也试着在语言规范中找到一个没有运气的答案.

我的问题是你知道这种行为吗?我在哪里可以找到关于这些的官方文件?

Edw*_*rzo 5

这可能无法直接回答有关获得官方文档规范来验证此行为的问题,但我们可以根据 MDN 中提供的源代码得出我们的结论,特别是在Function.prototype.bind()的文档中,在Polyfill部分下,他们提供一个 polyfillbind函数的示例。

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
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype; 
    }
    fBound.prototype = new fNOP();

    return fBound;
  };
}
Run Code Online (Sandbox Code Playgroud)

我们可以看到该oThis参数用在fBoundbind函数最终返回的闭包中。

这意味着当您调用该bind函数时,您将获得一个闭包函数作为回报,该函数在被调用时访问oThis在原始调用中作为参数提供的自由变量bind

因此,无论您重新绑定绑定fBound函数多少次,该函数已经永远绑定到oThis其闭包中的原始上下文。

MDN 文档还指向Raynos 绑定实现以供进一步参考,这似乎也对应于这个示例。