我正在尝试理解 JavaScript 中基于原型(prototype)的继承。我读了很多书并用谷歌搜索了几个小时。现在,我需要连接所有这些信息,希望你能帮助我。
如果以下 3 个陈述正确:
- JavaScript 中的每个对象都有一个特殊的内部属性,我们可以通过
.__proto__
访问该属性。 . - 所有构造函数都有一个匿名对象属性,我们可以通过
.protootype
访问该属性。 . __proto__
实例对象的属性指向prototype
其构造函数的对象属性。
让我们创建以下构造函数,该函数创建一个 Dog 对象:
function Dog(name, color) {
this.name = name;
this.color = color;
this.bark = function() {
return `Bark, bark! My name is ${this.name}`;
}
}
现在让我们创建一个 Dog 对象的实例:
let mini = new Dog('mini', 'black');
如果我们现在打开控制台并返回mini,结果如下:
正如预期的那样,实例对象 mini 继承了其构造函数的所有属性和方法。
但是这些继承的属性和方法都不在其 __proto__
内。属性(property)。看起来它们都是直接继承到对象 mini 本身的。
现在让我们向构造函数的原型(prototype)对象添加一个新方法:
Dog.prototype.myBread = function() {
return `My bread is ${this.bread}`;
}
如果我们现在在控制台中返回 mini,我们会得到以下结果:
同样,正如预期的那样,新方法 myBread 被传递给我们的对象。但这一次它显示在 __proto__
内我们的对象 mini,它引用(指向)构造函数内的 prototype 对象 属性。
现在,根据上面的简单实验,我假设以下内容:
如果构造函数有自己的属性和方法,则它们不是其原型(prototype)对象的一部分。这些属性和方法直接位于构造函数对象上。
但是如果我们向
.protoype
添加属性或方法构造函数中,它们被添加到其原型(prototype)对象中。为了证明这一点,我们无法访问Dog.myBread();
但我们可以访问Dog.prototype.myBread();
添加到
.prototype
的属性和方法我们的构造函数着陆到构造函数的原型(prototype)对象,并且因为__proto__
我们的实例对象引用该原型(prototype)对象,我们可以在实例对象中访问它们。如果构造函数有自己的属性和方法,则它们不在其原型(prototype)对象内部。这些属性和方法直接位于对象上,并自动传递给其所有实例。在这种情况下
__proto__
而prototype属性不发挥任何作用,与继承过程无关!
现在,你能帮我看看我的假设是否正确吗? 我对最后一个假设特别好奇。
最佳答案
Each object in JavaScript has a special internal property that we can access via
.__proto__
没有。每个 JS 对象都有一个内部 [[prototype]] 链接,我们可以通过 Object.getPrototypeOf()
访问它。 __proto__
已弃用,并且不适用于所有对象。
All constructor functions have an anonymous object property, which we can access via
.protootype
.
是的,所有构造函数都有一个带有对象的 .prototype
属性,但我不确定为什么您将其称为“匿名”。
The [[prototype]] link of an instance object points to the
prototype
object property of its constructor.
不是针对属性,而是针对对象本身。如果您重新分配 Constructor.prototype = ...
,实例的 [[prototype]] 链接不会更改。当您调用 new
时,会使用 Constructor.prototype
的当前值设置链接,是的。
As expected the instance object mini has inherited all properties and methods of it's constructor.
不,您的第一个示例中没有继承。 bark
、color
和 name
属性由实例拥有。它们不属于构造函数,它们只是由实例上的构造函数代码创建的。
- If a constructor has its own properties and methods, they are not part of its prototype object. Those properties and methods sit directly on the constructor object.
是的,.prototype
或 .name
就是位于构造函数对象本身的属性。
(请注意,作为函数对象的每个构造函数也有一个指向 Function.prototype
的 [[prototype]] 链接,但这在这里并不是特别有趣)
- But if we add properties or methods to
.protoype
of a constructor, they get added to its prototype object. To prove it, we cannot accessDog.myBread();
but we can accessDog.prototype.myBread();
这听起来像是老生常谈,所以是的。
- Properties and methods, that are added to the
.prototype
of our constructor land in to the prototype object of the constructor and because the [[prototype]] of our instance object references that prototype object, we can access them in our instance object.
是的,这就是继承。
- If a constructor has its own properties and methods, they are not inside its prototype object. Those properties and methods sit directly on the object and are passed automatically to all its instances. In such case the
__proto__
and prototype property don't play any role and have nothing to do with the inheritance process!
是的,自己的属性与继承无关。
关于javascript - 原型(prototype)和 __proto__,哪种说法是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51522415/