我试图理解JavaScript中基于原型的继承。我读了很多书,然后用谷歌搜索了几个小时。现在,我需要连接所有这些信息,并希望您能为我提供帮助。
如果以下3条正确的话:
.__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__
属性内。似乎它们都是直接继承给对象 mini 本身。
现在让我们向构造函数的原型对象添加一个新方法:
Dog.prototype.myBread = function() {
return `My bread is ${this.bread}`;
}
如果我们现在在控制台中返回 mini ,则会得到以下结果:
再次,如预期的那样,将新方法 myBread 传递给我们的对象。但是这一次它显示在对象 mini 的__proto__
内部,该对象引用(指向)构造函数中的 prototype对象属性。
现在从上面的简单实验中,我假设以下内容:
如果构造函数具有自己的属性和方法,则它们不属于其原型对象。这些属性和方法直接位于构造函数对象上。
但是,如果我们向构造函数的.protoype
添加属性或方法,它们就会被添加到其原型对象中。为了证明这一点,我们无法访问Dog.myBread();
,但是我们可以访问Dog.prototype.myBread();
.prototype
中的属性和方法落入构造函数的 prototype对象中,并且因为我们实例的__proto__
对象引用该原型对象,我们可以在实例对象中访问它们。
如果构造函数具有自己的属性和方法,则它们不在其原型对象之内。这些属性和方法直接位于对象上,并自动传递给其所有实例。在这种情况下,__proto__
和 prototype属性不起作用,并且与继承过程无关!
现在,您能帮我看看我的假设是否正确? 我对最后一个假设特别好奇。
答案 0 :(得分:2)
JavaScript中的每个对象都有一个特殊的内部属性,我们可以通过
访问.__proto__
不。每个JS对象都有一个内部[[prototype]]链接,我们可以通过Object.getPrototypeOf()
访问该链接。 __proto__
已过时,在所有对象上不可用。
所有构造函数均具有匿名对象属性,我们可以通过
.protootype
访问该属性。
是的,所有构造函数都具有带有对象的.prototype
属性,但是我不确定为什么将其称为“匿名”。
实例对象的[[prototype]]链接指向其构造函数的
prototype
对象属性。
不是属性,而是对象本身。如果您要重新分配Constructor.prototype = …
,则实例的[[prototype]]链接不会更改。调用Constructor.prototype
时,链接是使用new
的当前值设置的。是的。
按预期,实例对象mini继承了其构造函数的所有属性和方法。
不,您的第一个示例中没有继承。 bark
,color
和name
属性由实例拥有。它们不属于构造函数,它们只是由实例上的构造函数代码创建的。
- 如果构造函数具有自己的属性和方法,则它们不属于其原型对象。这些属性和方法直接位于构造函数对象上。
是的,.prototype
或.name
是位于构造函数对象本身的属性。
(请注意,每个构造函数都是函数对象,也具有指向Function.prototype
的[[prototype]]链接,但这在这里并不是特别有趣)
- 但是,如果我们将属性或方法添加到构造函数的
.protoype
中,则会将它们添加到其原型对象中。为了证明这一点,我们无法访问Dog.myBread();
,但可以访问Dog.prototype.myBread();
这听起来像是在说实话,是的。
添加到构造函数的
.prototype
中的- 属性和方法落入构造函数的 prototype对象中,因为实例对象的[[prototype]]引用了原型对象,我们可以在我们的实例对象中访问它们。
是的,这是继承。
- 如果构造函数具有自己的属性和方法,则它们不在其原型对象之内。这些属性和方法直接位于对象上,并自动传递给其所有实例。在这种情况下,
__proto__
和 prototype属性不起作用,并且与继承过程无关!
是的,自己的属性与继承无关。
答案 1 :(得分:1)
编写Dog.myBread();
时,您尝试调用的不是对象instanceOf Dog,而是仅调用Object(function)Dog,就像另一种语言的static
字段一样