javascript - 复制对象数组

标签 javascript jquery arrays object

我在创建对象数组的副本时遇到问题。我无法获得指向新独立数组的新引用。

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 关键字创建)。两个数组仍然指向同一个对象,因此当从另一个包含相同对象引用的数组读取时,您也会看到这种变化。

demonstration image

要解决此问题,您还必须 make a copy数组中的每个对象。根据您的用例,您可以使用 Object.assignObject.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/

相关文章:

javascript - 无法使用 SonarQube 分析 Javascript 文件

javascript - Ajax 请求上的动态 JavaScript 文件会产生冲突

javascript - 该函数可以工作,但报告 this.refresh() 不是一个函数

javascript - 扩展 L.Control.Layers 悬停失败

javascript - 通过导致错误的元素成为目标来进行 Angular 跟踪

jquery - 选择具有相同类的所有元素,其中一些元素具有两个类

javascript - jquery中如何发送和获取查询参数

java - 返回数字的输出没有达到预期?

java - 如何从文件读取到数组列表

java - 如何打印 public void testDistanceBetween_AD 中的值