首页 > prototype中的属性的改变

prototype中的属性的改变

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没有改变.

请问这该如何解释?
谢谢


      取对象属性值的时候,优先取对象自己的属性值,如果自己没有对应属性,就取__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"

function Person(){
        }
        
        Person.prototype = {//对应的是实例化对象person1,person2的__proto__属性
            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';//person1.__proto__.name其实没有改变
        //person1.__proto__.name和person2.__proto__.name 指向的是同个值
        alert(person1.name);     //tom
        alert(person2.name);    //Nicholas
        
        person1.__proto__.age = 20;//直接修改__proto__对象属性
        alert(person1.age);     //20
        alert(person2.age);    //20

引用的问题
赋值符号(=)修改的是name,push方法修改的是friends的引用,两者修改的东西不一样
至于new了两个对象,它们初始的name和friends引用相同的对象这些,你自己慢慢理解


其实这个问题,我们还是可以先看看文档是怎么描述prototype这个东西的:

注意被选中的部分

原因是可能其他朋友已经提到了,prototype上的属性是在所有实例对象里共享的,除非你改变它。

//这个就属于改变,因为变量name指向的内容已经变了
person1.name = 'tom';

//这个就不属于改变,因为friends指向的内容仍然是之前那个数组
person1.friends.push("Van");

要修正你的问题也很简单,只要把friendsprototype上移到构造函数里,让他成为一个实例变量就好了:

function Person() {
    this.friends = ['Shelby', 'Court'];
}

Person.prototype = {name: 'Nicholas', age: 29};

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

person1.friends.push('Van');

console.log(person1.friends); //[ 'Shelby', 'Court', 'Van' ]
console.log(person2.friends); //[ 'Shelby', 'Court' ]
【热门文章】
【热门文章】