如何正确使用 Object.setPrototypeOf()

Al *_* R. 9 javascript ecmascript-6

所以我一直在了解 JavaScript 的一些新特性,并且一直在阅读 Object.setPrototypeOf()。我从MDN 中遇到了这段代码,它处理从常规对象的继承。但我对他们在这里如何使用 Object.setPrototypeOf() 感到困惑。我希望他们写

Object.setPrototypeOf(Dog, Animal) 
Run Code Online (Sandbox Code Playgroud)

与下面的操作相反。他们为什么这样写?

var Animal = {
   speak() {
     console.log(this.name + ' makes a noise.');
   }
};

class Dog {
   constructor(name) {
   this.name = name;
  }
}

Object.setPrototypeOf(Dog.prototype, Animal);// If you do not do this you will get a TypeError when you invoke speak

var d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
Run Code Online (Sandbox Code Playgroud)

tri*_*cot 5

调用的原因Object.setPrototypeOf是为了确保Dog构造函数创建的任何对象都将Animal在其原型链中获取该对象。设置构造函数本身的原型是错误的(不要与构造函数的prototype属性混淆,这确实是用词不当),因为构造函数在d的原型链中没有位置。

创建的Dog对象不会进入Dog其原型链,而是Dog.prototype. Dog仅仅由对象创建的车辆,它不应该自己成为原型链的一部分。

可以改为在Dog构造函数中执行此操作:

Object.setPrototypeOf(this, Animal)
Run Code Online (Sandbox Code Playgroud)

这使得原型链的长度缩短了一步,但缺点是现在d instanceof Dog将不再如此。它只会是一个Animal. 这是一个坑,它解释了为什么保留原始Dog.prototype对象是好的,同时设置原型为Animal,因此现在d既是 aDog又是 an Animal

在此处阅读有关此主题的信息。我会宣传我自己对该问答的回答

  • 实际上,语言中使用“prototype”这个词的方式令人困惑:“setPrototypeOf”更多地与“__proto__”相关,然后与“prototype”相关。后者最好以不同的方式命名,尽管我想不出一个简短的名字。类似于`prototypeForObjectsCreatedByThisConstructor`,但这可能有点过于冗长;-) 所以当我们在英语句子中使用prototype这个词时,我们最常指的是`__proto__`,而不是`prototype`。 (2认同)