原型对象的性质(六):原型对象的问题

原型对象的问题

先来看两个例子:

1.当在实例中为引用类型的属性赋值时,原型对象的属性值并没有修改

function Person(){
    hobby:"painting"
}
Person.prototype={
    constructor:Person,
    name:"Nicholas",
    age:29,
    job:"SoftWare Engineer",
    friends:["Shelly","Court"],
    sayName:function(){
    console.log(this.name);
}
};
var person1=new Person();
var person2=new Person();
person1.friends=["Shelly","Court","Ken"];
console.log(person1.friends);//[ 'Shelly', 'Court', 'Ken' ]
console.log(person2.friends);//[ 'Shelly', 'Court']
console.log(person1.friends===person2.friends);//false

2.而在实例中对引用类型使用方法时,原型对象的属性值却被修改了。

person1.friends.push("Ken");
console.log(person1.friends);//[ 'Shelly', 'Court', 'Ken' ]
console.log(person2.friends);//[ 'Shelly', 'Court', 'Ken' ]

赋值改变了friends的指向,为什么原型对象没有改变,而使用方法时,又为什么能够改变原型对象的属性值呢?这个问题该怎么解释呢?
在segmentFault中发现了一个相似的问题,终于得到了比较合理的解释:
引用时会从当前对象开始一直到原型链的最顶端,直到找到指定的属性。而赋值操作只会对当前实例的属性产生影响,如果没有就新建一个,而不会去原型链上找。
链接:https://segmentfault.com/q/1010000004500887
因此,就第二种情况,修改实例中的引用类型,就会导致原型对象中的引用被同时修改,而所有的实例都将共享同一个属性值,就不能达到实例想要拥有属于自己的属性的要求了。

总结:

原型模式省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。这种共享对于包含引用类型值的属性来说,最大问题就是由原型对象共享的本性所导致的。

猜你喜欢

转载自blog.csdn.net/yangyuqingabc/article/details/82953429