为什么我不能设置使用 'bind' 创建的函数的 'prototype'?

Why can't I set the 'prototype' of a function created using 'bind'?

考虑这段代码:

function foo(something) {
  this.a = something;
}

var obj1 = {};

var bar = foo.bind(obj1);

现在不执行以下语句:

bar.prototype.newprop = "new"; // Cannot execute this

据我了解,每个函数都有一个原型对象。那为什么不能执行上面的语句呢?

bar 确实是一个函数,我们可以这样称呼它:

bar(2);
console.log(obj1.a); // 2

.bind() 返回的函数没有原型对象。你可以给它一个:

bar.prototype = { newprop: "new" };

"every function has a prototype object" 是不正确的。每个函数 可以 有一个原型对象,但是 "prototype" 属性 的值可以是任何东西,包括 nullundefined

此外,还有 "special" 个函数在所有情况下的行为可能都不像普通函数。

查看 specification:

Function.prototype.bind ( thisArg , ...args)

[...]

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

As I understood, every function has a prototype object.

好吧,每条规则都有例外 :-) 您发现了一个:绑定函数没有 .prototype 属性 因为它们不需要它。当您使用 new 调用绑定函数时,它会调用原始函数作为构造函数,使用原始的 .prototype 对象作为新实例的原型。

事实上,自 ECMAScript 6 以来,许多函数没有 .prototype 属性 对象,因为它们不是构造函数 - 它们不能用 new 调用,所以它们不需要它。其中有

  • 箭头函数 (() => {…})
  • 方法(对象字面量中的method() { … }和类)
  • 内置非构造函数(如Math.sin

prototype 添加属性意味着您想通过使用函数作为构造函数来创建对象。

当您通过在函数上调用 new 来创建对象时,this 值是正在创建的新对象。所以 bind this 到另一个值是没有意义的。