就在我以为我已经了解了JS时,我卡在了这个问题上:
function Obj() {
console.log('x: %s, o.x: %s', this.x++, this.o.x++);
}
Obj.prototype.x = 1;
Obj.prototype.o = {x: 1};
希望达成的目标:
> new Obj
x: 1, o.x: 1
> new Obj
x: 1, o.x: 1
> new Obj
x: 1, o.x: 1
实际:
> new Obj
x: 1, o.x: 1
> new Obj
x: 1, o.x: 2
> new Obj
x: 1, o.x: 3
因此,如果原型属性是引用类型,则它将在所有实例之间共享,但如果它是非引用类型,则会为每个实例重新初始化;为了证实这个假设,我测试了一些其他类型,如
string
(与number
相似)和array
(与object
相似)。
我已经确定,如果我在构造函数中重新初始化对象属性,就可以避免这个陷阱,像这样:
function Obj() {
this.o = {x: 1};
}
这似乎非常不正规(我需要手动重新初始化属性,但仅当它们是引用对象时)。
有人可以解释一下发生了什么吗?
(new Obj).o === (new Obj).o
- [继承的] 属性都指向同一个对象,其x
属性会递增。 - Bergiarray
也是一个对象)是按引用复制的。问题在于,当您修改o
对象的x
属性时,您正在修改原型链中相同o
对象的引用。” - gion_13