.bind multiple times

JavaScript

在 JavaScript 注册事件回调的时候,经常会用到 .bind 方法绑定 this 的指向。(关于 .bind 方法的使用,可以参考 MDN)。

这里有一个关于 .bind 使用的细节:根据 ECMAScript 规范的描述,.bind 只能修改 this 指向一次

具体的规范如下:

NOTE 2: If Target is an arrow function or a bound function exotic object then the thisArg passed to this method will not be used by subsequent calls to F.

这里规范明确了两个事情:

  1. .bind 函数对已经 bind 过的函数是无效的;
  2. .bind 函数对箭头函数是无效的。

可以简单通过下面的代码验证这个行为:

function test(...args) {
  console.log(this.name, ...args);
}

const first = test.bind({ name: 'first' }, 1);
const second = first.bind({ name: 'second' }, 2);

first();  // output: "first 1"
second(); // output: "first 1 2"

可见,.bind 函数可以继续增加预置的函数参数,但是对 this 的指向无法继续改变了。

另外,在规范里还提到了一个细节:经过 .bind 之后的函数不再有 prototype 了。具体的规范如下:

NOTE 1: Function objects created using Function.prototype.bind are exotic objects. They also do not have a “prototype” property.

验证代码:

function Animal() { }
Animal.prototype.say = function () { console.log(this.name); }

const Cat = Animal.bind({ name: 'cat' });
console.log(Cat.prototype); // output: undefined