首页 > 解决方案 > Javascript深拷贝(值)在数组中不起作用

问题描述

嗨,我正在为即将到来的项目使用 node.js 和 Javascript。我有一个名为templateValues的模板对象数组。

现在我想将这两个具有更改 id 的对象复制到一个新数组myArray中。

let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
let myArray = [];

for (let index = 0; index < 10; index++) {
 myArray =  myArray.concat(templateValues.map(e => {
   e.id = Math.random(); // suppose this gives a unique id
   return e;
  }).slice(0));	
}
console.log(myArray);

输出

{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
...

即使我对更改后的templateValues -array 执行 slice(0) 以获得“数据副本”,为什么id都相同?!

标签: javascriptarrays

解决方案


当您调用 slice 时,您正在修改数组对象,而不是数组本身的内容。您的示例中没有克隆底层对象的代码行,因此,当您设置时e.id = Math.random(),您正在一遍又一遍地编辑同一个对象。

此处的解决方法是在修改 e 之前对其进行克隆。在编辑它之前尝试Object.assign({}, e)制作每个项目的浅表副本。

请参见以下示例:

let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
let myArray = [];

for (let index = 0; index < 10; index++) {
    myArray =  myArray.concat(templateValues.map(e => {
       const eCopy = Object.assign({}, e, {id: Math.random()})
       return eCopy;
  }).slice(0)); 
}
console.log(myArray);

您还可以使用ES2018 对象扩展语法来实现相同的结果。只需将 Object.assign 替换为{...e, id: Math.random()}


推荐阅读