JavaScript中,不是在实例中修改prototype属性会在该实例中隐藏类的prototype属性,而其他实例不受影响吗?
function Person(){
}
Person.prototype = {
name : "Nicholas",
age : 29,
friends : ["Shelby", "Court"]
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
person1.name = 'tom';
alert(person1.name); //tom
alert(person2.name); //Nicholas
请看代码,
person1.friends.push("Van");给friends数组添加了元素“van”。person1.friends、person2.friends都输出了"Shelby,Court,Van"。
(是不是说明prototype里的数组也改变了?)
person1.name = 'tom';在person1中将name属性改成了‘tom’。
person1.name输出了‘tom’,person2.name则输出了‘Nicholas’。
说明prototype里的name没有改变.
请问这该如何解释?
谢谢
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
取对象属性值的时候,优先取对象自己的属性值,如果自己没有对应属性,就取
__proto__属性下的对应属性(即所拓展对象的属性或构造函数的prototype属性啦),如果还是没有,才返回undefined。说完取,就说修改啦。通过对象
.的赋值修改只能修改对象下的直接属性,是永远不会修改__proto__属性下的对应属性的。比如说,person1.name="tom";这一步实际的操作是,直接将"tom"赋值给person1.name属性,而不是person1.__proto__.name;那么person1.friends.push("Van");为什么能修改成功呢?注意啦,person1.friends.push("Van");不是赋值修改,它是先取出person1.__proto__.friends对象,然后对其进行操作的,所以能够修改成功。如果person1.friends=["jay","jane"];,你就会发现person2.friends的值还是"Shelby", "Court"。引用的问题
赋值符号(=)修改的是name,push方法修改的是friends的引用,两者修改的东西不一样
至于new了两个对象,它们初始的name和friends引用相同的对象这些,你自己慢慢理解
其实这个问题,我们还是可以先看看文档是怎么描述
prototype这个东西的:原因是可能其他朋友已经提到了,
prototype上的属性是在所有实例对象里共享的,除非你改变它。要修正你的问题也很简单,只要把
friends从prototype上移到构造函数里,让他成为一个实例变量就好了: