在javascript中将对象数组复制到另一个数组中(Deep Copy)

jsb*_*sht 19 javascript arrays google-chrome deep-copy node.js

使用slice(0)和concat()在javascript中将对象数组复制到另一个数组中不起作用.

我已经尝试了以下测试,如果我使用这个获得深度复制的预期行为.但是,在复制的数组中进行更改后,原始数组也会被修改.

var tags = [];
for(var i=0; i<3; i++) {
    tags.push({
        sortOrder: i,
        type: 'miss'
    })
}
for(var tag in tags) { 
    if(tags[tag].sortOrder == 1) {
        tags[tag].type = 'done'
    }
}
console.dir(tags)

var copy = tags.slice(0)
console.dir(copy)

copy[0].type = 'test'
console.dir(tags)

var another = tags.concat()
another[0].type = 'miss'
console.dir(tags)
Run Code Online (Sandbox Code Playgroud)

如何将数组的深层副本复制到另一个数组中,以便在复制数组中进行更改时不会修改原始数组.

小智 68

尝试

var copy = JSON.parse(JSON.stringify(tags));
Run Code Online (Sandbox Code Playgroud)

  • @Aerious嗯,这是有效的,因为你将数组/对象序列化为一个字符串.解析该字符串时,将实例化全新对象,就像从某些api收到有效负载一样.但是,引用不会被保留,因此如果您有指向其他元素的数组元素,这将是危险的. (7认同)

Mar*_*rko 14

请尝试以下方法

// Deep copy
var newArray = jQuery.extend(true, [], oldArray);
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请查看此问题在JavaScript中深度克隆对象的最有效方法是什么?


bp4*_*p4D 5

如前所述,Here .slice(0)将有效地克隆具有原始类型元素的数组。但是在您的示例tags数组中包含匿名对象。因此,对克隆数组中这些对象的任何更改都会反映在tags数组中。

@dangh 上面的回复取消了这些元素对象的引用并创建了新的对象。

这是另一个解决类似情况的线程