Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 引用基类中的对象时的保留_Javascript_Oop_Inheritance - Fatal编程技术网

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;
     }
 };
下面