为什么对象原型中的属性不能被对象修改?

时间:2015-12-24 09:19:14

标签: javascript prototype

当我执行以下js代码时,我发现了一些奇怪的东西:

function Contact(name, email) {
    this.name = name;
    this.email = email;
}

Contact.prototype = {
    a: 10,
    b: 20
};

var obj = new Contact('ssj', 'ssh');
obj.a = 'ssjssh';
console.log(obj);
console.log(Contact.prototype);
//output: { name: 'ssj', email: 'ssh', a: 'ssjssh' },{ a: 10, b: 20 }

所以我的问题是为什么obj.a = 'ssjssh'只在obj中添加了一个属性,而不是在Contact.prototype中更改属性a

4 个答案:

答案 0 :(得分:4)

原型中的属性仅在读取时用作默认值。这允许类的所有成员获取属性的相同初始值或默认值。但是每个对象都可以通过拥有自己的值来覆盖这些默认属性。分配给属性时,它总是转到对象自己的属性,否则将无法覆盖默认值。

答案 1 :(得分:2)

来自Marijn Haverbeke的Eloquent Javascript

  

向对象添加属性时,是否存在于对象中   原型与否,该属性被添加到对象本身,其中   今后将把它作为自己的财产。如果有财产   在原型中同名,此属性将不再受影响   物体。原型本身没有改变。

答案 2 :(得分:1)

这是查询和修改对象属性的方式 最初a不是obj的自有属性,而是继承的(与nameemail相反,它们是自己的属性)。查询时,解释器在原型链中搜索属性,并在a中找到Contact.prototype。 为继承的a分配值时,JavaScript会在对象中创建一个新的属性,而不会影响原型。任何后来对自己属性的修改都不会影响原型。现在将隐藏继承的属性 如果您想直接修改原型,只需使用Contact.prototype.a = 'new value'即可。但请注意,这将影响使用继承的Contact属性的a构造函数的所有实例。
使用method obj.hasOwnProperty('a')检查该属性是属于还是已继承。

答案 3 :(得分:0)

语句var obj = new Contact('ssj', 'ssh');将在内部创建一个新对象newObj(假设jst供参考),它将返回newobj。


在返回newObj之前,语句

this.name = name;
this.email = email;

将设置newObj的名称&将电子邮件发送给' ssj' &安培; ' SSH'由于隐含约束,这个'与newobj绑定。

现在返回后obj将指向newObj,其值为 name-'ssj'& email-'ssh'

在此之后,您正在创建一个新属性" a"在obj。

我们之前创建的

newObj通过[[prototype]]链接内部指向Contact.prototype。所以newObj& Contact.prototype是不同的对象&你在newobj上设置属性。

通过遮蔽和a未标记为只读的概念,它不会遍历原型链,而是直接在直接对象上设置a属性。