Javascript 引用基类中的对象时的保留
在以下代码中:Javascript 引用基类中的对象时的保留,javascript,oop,inheritance,Javascript,Oop,Inheritance,在以下代码中: function Base() { this.colors = ["red", "green", "blue"]; } var base = new Base(); var derived1 = Object.create(base); console.log(derived1.colors); // ["red", "green", "blue"] var derived2 = Object.create(base); console.log(derived2.c
function Base() {
this.colors = ["red", "green", "blue"];
}
var base = new Base();
var derived1 = Object.create(base);
console.log(derived1.colors); // ["red", "green", "blue"]
var derived2 = Object.create(base);
console.log(derived2.colors); // ["red", "green", "blue"]
derived1.colors.push("white");
console.log(derived1.colors); // ["red", "green", "blue", "white"]
console.log(derived2.colors); // ["red", "green", "blue", "white"]
有两个对象是从基派生的,分别是derived1和derived2。我们只将一个元素推入derived1.colors,但derived2.colors也会被修改。我知道这是因为它们共享相同的原型,并且其属性颜色是引用类型。然而,基类在引用类型中具有属性是很常见的,因此在JavaScript中使用inheritace看起来风险很大
我的问题是:如果可以的话,如何解决这个关于继承的问题,以便为derived1和derived2制作两个颜色副本?如果没有,在实际产品代码中避免它的最佳实践是什么?您正在执行
var base=new base()代码>并将其设置为两个对象(derived1和derived2)的原型。在javascript中,它们被设置为引用,这意味着您对其中一个进行修改,其他引用将得到相同的更改
这样做:
derived1.colors.push("white");
您正在将该值推送到两个对象上相同的原型对象(引用)的属性。因此,您可以看到这种行为,因为对象的原型都指向您先前创建的同一对象
您可以简单地执行以下操作:
var derived1 = Object.create(new Base());
console.log(derived1.colors); // ["red", "green", "blue"]
var derived2 = Object.create(new Base());
console.log(derived2.colors); // ["red", "green", "blue"]
如果这是一个问题,我建议不要直接公开数组,而是创建一个选择器和mutator(getter和setter)来访问和修改数据。通过这种方式,您可以保证完整性并将状态存储在正确的级别
function Base() {
this.colors = function (colors) {
if (colors === undefined) {
return this._colors || (this._colors = ["red", "green", "blue"]);
} else {
this._colors = colors;
}
};
}
var base = new Base();
var derived1 = Object.create(base);
console.log(derived1.colors()); // ["red", "green", "blue"]
var derived2 = Object.create(base);
console.log(derived2.colors()); // ["red", "green", "blue"]
derived1.colors().push("white");
console.log(derived1.colors()); // ["red", "green", "blue", "white"]
console.log(derived2.colors()); // ["red", "green", "blue"]
最大的变化是您必须将颜色作为函数调用。看
或者,如果您知道不支持旧的JS运行时,您可以使用实际的getter和setter
function Base() {}
Base.prototype = {
get colors() {
return this._colors || (this._colors = ["red", "green", "blue"]);
},
set colors(val) {
this._colors = val;
}
};
下面