所以我一直在快速学习JavaScript的一些新特性,并且一直在阅读关于Object.setPrototypeOf()的内容。我偶然发现了MDN中的这段代码,它处理从常规对象继承的问题。但是我对他们在这里如何使用Object.setPrototypeOf()感到困惑。我希望他们写
Object.setPrototypeOf(Dog, Animal)
而不是下面他们做的。他们为什么这样写?
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.
3条答案
按热度按时间niknxzdl1#
调用
Object.setPrototypeOf
的原因是为了确保任何由Dog
构造函数创建的对象都能在其原型链中获得Animal
对象。设置构造函数本身的原型是错误的(不要与构造函数的prototype
属性混淆,后者实际上是一个用词不当),因为构造函数在d
的原型链中没有位置。创建的
Dog
对象在其原型链中不获得Dog
,但是Dog.prototype
.Dog
* 只是 * 创建对象的载体,它本身不应该成为原型链的一部分。您 * 可以 * 在
Dog
构造函数中执行此操作:这使得原型链的长度缩短了一步,但缺点是现在
d instanceof Dog
将不再是真的,它将只是一个Animal
,这是一个遗憾,这也解释了为什么保留原来的Dog.prototype
对象是好的,而将 * 其 * 原型设置为Animal
,因此现在d
既是Dog
又是Animal
。阅读关于这个主题here的文章。我会把my own answer推广到那个问答中。
vwkv1x7d2#
1)Animal是Object文字
2)对象文本没有prototype属性
3)语法为
4)通过这样做,我们继承了的属性
对象文本(Animal)到另一个文本或构造函数(Dog)
5)在这里,狗的原型是从动物设定的。
此方法(Object.setPrototypOf())将对Animal的方法的引用设置为对Dog的prototype的引用
yduiuuwa3#
我们可以使用
{__proto__:...}
来做同样的事情:{__proto__: Animal}
是定义prototype chain
的一种方式,这里是动物中定义的{__proto__: {speak:function(){...}}
。为了理解这一点,我们来看看这个链的步骤。当我们这样做
Dog.speak()
js不能找到函数speak
内的狗。所以它向上链一次,并找到speak
内的动物。正如预期的输出“Mitzie制造噪音。"从概念上讲,
Object.setPrototypeOf(Dog.prototype, Animal)
与Dog.prototype.__proto__=Animal
相同,我们将此设置Dog.prototype.[[Prototype]]
称为Animal,[[Prototype]]
是指向链上一级对象的链接。下面的示例替换为使用
__proto__
定义原型链。最后,您可以只使用
class extends..
。正如您所看到的,这种方法是推荐的最简单的方法;)