【发布时间】:2016-04-01 10:29:59
【问题描述】:
我知道 JavaScript 中继承的概念是通过原型链,但我不确定我是否理解正确。当一个属性被读取时,引擎会先搜索实例自身的属性,如果没有找到会搜索实例的[[Prototype]]属性,该属性是对创建实例的函数原型的引用,搜索将继续,直到到达 Object.prototype。对于以下代码:
var person1 = {
name: "Qiushi",
sayName: function() {
console.log(this.name);
}
};
person1.sayName(); // Qiushi
var person2 = Object.create(person1);
person2.name = "Alex";
console.log(person2.hasOwnProperty("sayName")); // false
person2.sayName(); // Alex
当person2继承自person1时,person2可以使用person1中定义的方法。但是 sayName 方法不是 person1 原型的属性,而是它自己的属性。我的问题是,由于方法搜索仅遵循原型链,person2 将如何使用不在此链中的方法?
-------------------最终编辑------------- ------------
如果你对这个问题有同样的担忧,请阅读我和金博的对话。
【问题讨论】:
-
它是在链中,只是不拥有(未在
person2原型上定义)。这就是为什么我们首先使用hasOwnProperty()。 -
这里有一点需要考虑:JavaScript 中没有继承。没有任何东西可以从任何地方继承任何东西。只有一个对象的单链表,称为原型链。按顺序在该列表中的对象中搜索具有给定名称的属性。一个对象定义了某个属性(然后
hasOwnProperty()对那个特定对象为真),或者它在链中的一个父对象具有(然后hasOwnProperty()对那个特定父对象为真,但对初始对象为假),或没有,则该属性未定义。 -
@Tomalak:“JavaScript 中没有继承”是不真实的。仅仅因为继承机制很容易解释,这并不意味着它不是继承。 Java 和 C++ 的继承机制也很容易解释。
-
@T.J.Crowder 我知道,我们同意这一点。评论的目的是打破继承属性以某种方式成为原型链末端对象的实际部分的常见思维模式。如果我替换对象原型链的一个元素,该对象立即看起来具有不同的属性。原型继承模仿了继承的效果,但所讨论的对象并没有真正获得它们响应的属性(与 Java/C++ 中的工作方式相反)。
-
@Tomalak:这不是模仿,只是一种不同的机制。同意它的不同之处,以及如何让人们感到惊讶。 (有趣的是,您还经常看到 OP 考虑单独对象的 Java 问题,一个用于基类部分,另一个用于派生部分,并且以 that 的方式感到困惑。:-))
标签: javascript inheritance prototype