我在创建对象数组的副本时遇到问题。我无法获得指向新独立数组的新引用。
function OBJ1(name, tags) {
this.myname = name;
this.mytags = tags;
this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
result = createarray2();
}
function createarray1() {
var myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
var newarray = $.extend(true, [], OBJ1_array); // newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}
输出:
testscript.js:45 categories (3) [{…}, {…}, {…}]0: {myname: "CHANGED", mytags: Array(3), myvalue: 0}1: {myname: "others", mytags: Array(3), myvalue: 0}2: {myname: "total", mytags: Array(3), myvalue: 0}length: 3__proto__: Array(0)
testscript.js:46 newArray (3) [{…}, {…}, {…}]0: {myname: "CHANGED", mytags: Array(3), myvalue: 0}1: {myname: "others", mytags: Array(3), myvalue: 0}2: {myname: "total", mytags: Array(3), myvalue: 0}length: 3__proto__: Array(0)
我预计 OBJ1_array[0].myname="CHANGED";
对新创建的数组 newArray
没有影响。
我尝试过但没有奏效的事情:
var newArray = OBJ1_array.map(a => ({...a}));
var newarray=$.extend(true,[],OBJ1_array);
我该如何解决这个问题?
最佳答案
$.extend
文档说明如下:
Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. Properties that are an object constructed via
new MyCustomObject(args)
, or built-in JavaScript types such as Date or RegExp, are not re-constructed and will appear as plain Objects in the resulting object or array.
这意味着其中包含所有普通对象的数组将被深度合并/复制。但是,不会重建使用 new
关键字创建的对象。这给我们留下了以下场景:
数组副本工作得很好,但是由于数组中的元素是使用 new
关键字创建的,所以它们不会进一步合并。当改变数组本身(压入、弹出等)时,您可以看到该数组确实是一个副本。
这里的问题是您访问数组中的一个元素并更改对象(使用 new
关键字创建)。两个数组仍然指向同一个对象,因此当从另一个包含相同对象引用的数组读取时,您也会看到这种变化。
要解决此问题,您还必须 make a copy数组中的每个对象。根据您的用例,您可以使用 Object.assign
或 Object.create
在盲目使用它们之前先看看文档。
我还针对您面临的问题创建了一个最小示例,以便您更好地理解该问题。
// setup
var array1, array2, array3, array4;
function Dummy(name) { this.name = name }
// test #1 - using plain objects
array1 = [{ name: 'Foo' }];
array2 = $.extend(true, [], array1);
array1[0].name = 'Bar';
console.log(array1[0].name, array2[0].name);
// test #2 - using the `new` keyword
array3 = [new Dummy('Foo')];
array4 = $.extend(true, [], array3);
array3[0].name = 'Bar';
console.log(array3[0].name, array4[0].name);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
关于javascript - 复制对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55060656/