当我执行以下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
?
答案 0 :(得分:4)
原型中的属性仅在读取时用作默认值。这允许类的所有成员获取属性的相同初始值或默认值。但是每个对象都可以通过拥有自己的值来覆盖这些默认属性。分配给属性时,它总是转到对象自己的属性,否则将无法覆盖默认值。
答案 1 :(得分:2)
来自Marijn Haverbeke的Eloquent Javascript:
向对象添加属性时,是否存在于对象中 原型与否,该属性被添加到对象本身,其中 今后将把它作为自己的财产。如果有财产 在原型中同名,此属性将不再受影响 物体。原型本身没有改变。
答案 2 :(得分:1)
这是查询和修改对象属性的方式
最初a
不是obj
的自有属性,而是继承的(与name
和email
相反,它们是自己的属性)。查询时,解释器在原型链中搜索属性,并在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
属性。