Javascript:共享数组属性的两个不同对象?

时间:2017-11-02 18:08:53

标签: javascript arrays object

在我的JavaScript项目中,我定义了一个对象,然后使用Object.create()创建多个实例。该对象具有多个(字符串和整数)属性,每个属性对于每个实例都是唯一的。但是,如果我使用数组属性,则所有实例共享相同的数组。

此代码很容易证明:

TestThing = {
    code: "?",
    intlist: [],

    addint(i) {
        alert("Adding " + i + " to " + this.code + ", list had " + this.intlist.length + " ints");
        this.intlist.push(i);
    }
}

var thing1 = Object.create(TestThing);
thing1.code = "Thing 1";
var thing2 = Object.create(TestThing);
thing2.code = "Thing 2";

thing1.addint(11);
thing2.addint(42);

alert(thing2.intlist);  // will output 11,42

那是什么原因造成的?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

使用reference-type属性,每个子节点都会获得对同一对象的引用。所有实例都可以看到任何孩子对该对象所做的任何更改。

您需要实现构造函数来设置属性,或者让第一次使用属性的代码设置它。 (但是,如果你想使用构造函数 Object.create,你必须自己调用它; Object.create不会为你调用它。 )

你可以这样做......

TestThing = {
    code: "?",
    intlist: null,
    addint : (i) => {
        if (!this.intlist) this.intlist = [];
        alert("Adding " + i + " to " + this.code + ", list had " + this.intlist.length + " ints");
        this.intlist.push(i);
    }
}

或者,更不容易出错(虽然放弃Object.create)......

class TestThing {
    constructor(code) {
        this.code = code;
        this.intlist = [];
    }

    addint(i) {
        alert("Adding " + i + " to " + this.code + ", list had " + this.intlist.length + " ints");
        this.intlist.push(i);
    }
}

var thing1 = new TestThing("Thing 1");
var thing2 = new TestThing("Thing 2");

thing1.addint(11);
thing2.addint(42);

alert(thing2.intlist);  // will output 42

不幸的是,如果您正在为网络浏览器编码,那么IE(甚至IE 11)似乎并不支持class。因此,您必须坚持使用旧的定义类的方式。

TestThing = function(code) {
    this.code = code;
    this.intlist = [];
};

TestThing.prototype = {
    addint: function(i) {
        alert("Adding " + i + " to " + this.code + ", list had " + this.intlist.length + " ints");
        this.intlist.push(i);
    }
};

答案 1 :(得分:-2)

要解决此问题,请使用concat代替推送,如下所示:

this.intlist = this.intlist.concat(i);

为什么会这样?因为push改变了数组,concat没有,并且javascript中的数组也是一个对象,因此,对该数组的内存引用是相同的。