原型对象的问题
先来看两个例子:
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
因此,就第二种情况,修改实例中的引用类型,就会导致原型对象中的引用被同时修改,而所有的实例都将共享同一个属性值,就不能达到实例想要拥有属于自己的属性的要求了。
总结:
原型模式省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。这种共享对于包含引用类型值的属性来说,最大问题就是由原型对象共享的本性所导致的。