正如 Sean Vieira 所解释的,第一种方法与第二种方法不同。在第一个方法中,实例继承自Person.prototype。在第二种方法中,实例直接继承自Object.prototype。
方法一:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| Person.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
方法二:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
有趣的是,上面的图表向您展示了 对象从 JavaScript 中的其他对象继承,而不是从构造函数。因此,当您创建 new Person 时,实例继承自 Person.prototype,而不是 Person 本身。
这些相关信息如何?对于初学者,它表明您不需要创建构造函数来创建对象的实例。相反,您可以直接创建原型对象,如下所示:
var person = {
create: function (name, gender) {
var person = Object.create(this);
person.gender = gender;
person.name = name;
return person;
},
speak: function () {
alert("My name is " + this.name + ".");
}
};
在上面的例子中person 等价于Person.prototype。您现在可以创建person 的实例,如下所示:
var bob = person.create("Bob", "M");
bob 的原型链如下所示:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
^
|
| __proto__
|
+------------------+
| bob |
+------------------+
那么为什么要创建这样的对象呢?
- 看起来更干净。一切都封装在一个对象字面量中。
- 对象继承自对象更容易理解。不需要构造函数。
- 您不需要使用
new 来创建实例。这个solves 是lot 的problems。
有关此模式的更多信息,请阅读我在 "Why Prototypal Inheritance Matters" 上的博文。