理解对象构造函数中使用的原型

时间:2014-08-07 18:17:57

标签: javascript prototype

我理解原型可用于将属性扩展到他们的孩子。但是,我不明白为什么你想要一个" Object.prototype.property"在主对象构造函数类本身?

在Person构造函数中,为什么Person.prototype.name = "Nicholas"; VS this.name = "Nicholas";

 function Person(){

 Person.prototype.name = "Nicholas";
 Person.prototype.age = 29;
 Person.prototype.job = "Software Engineer";
 };

 var person1 = new Person();
 var person2 = new Person();

 person1.name = "Greg";
 alert(person1.name);   //"Greg" – from instance
 alert(person2.name);   //"Nicholas" – from prototype

2 个答案:

答案 0 :(得分:1)

Person.prototype.name = 'Nicholas'this.name = 'Nicholas' 相同。

让我们自己看看:

var PersonA = function () {
    this.name = 'Nicholas';
    this.species = 'Homo Sapiens'
    return this; // optional
};
var PersonB = function () {
    return this;
};
PersonB.prototype.name = 'Nicholas';
PersonB.prototype.species = 'Homo Sapiens'

var personA = new PersonA();
console.log(Object.keys(personA)); // logs ["name", "species"]

var personB = new PersonB();
console.log(Object.keys(personB)); // logs []

console.log(personA.species === personB.species); // logs true

显然,personA有2个密钥,"name""species";虽然personB没有钥匙!。

然而,personB 2个密钥的原型,"name""species"

现在,如果你创建了一百万个PersonA个对象,那么每个这样的对象都会有一个 "name": "Nicholas""species": "Homo Sapiens"键值对。

另一方面,创建一百万个PersonB对象会更加节省内存,因为每个这样的对象根本没有键值对!同时,"name""species"都可以通过原型(原型继承)获得。

仔细研究改进:

让我们检查对象obj的细化,比如obj.foo

  • 如果"foo"obj的属性,则返回相应的值。
  • 否则,会查看obj的原型。
  • 如果该原型具有属性"foo",则返回相应的值。
  • 否则会查看原型的原型。
  • 此过程一直持续到我们点击Object.prototype

因此,就记忆而言,PersonB优于PersonA。这就是原型继承之美。

希望这有帮助。

答案 1 :(得分:1)

在构造函数中设置prototype属性几乎肯定是一个错误。原型是所有子对象的共享状态。您可能希望在构造函数中更新原型的唯一原因是您是否正在存储共享数据。例如,您可以增加一个计数器,或者添加一个总和。但是你几乎不会期望在构造函数中的原型上设置像“name”这样的简单字符串属性。