javascript - 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都相同?!
解决方案
当您调用 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()}
推荐阅读
- android - Hilt (Android):找不到符号返回 DaggerApp_HiltComponents_ApplicationC.builder()
- java - JAR运行时如何将多个属性定义为参数?
- puppet - 使用已定义类型的尚未发布的 puppet 模块
- python - 为什么这个查询会在 Python 中抛出这个错误?
- node.js - nodeJS - 即使查询结果很好,findOne 查询也没有转换为 JSON 对象
- ios - 如何在 iOS 14、SwiftUI 2 中以编程方式更改 PageTabView?
- c# - 使用 ADO.NET System.Data.SQLite 从 SQLite DB 读取 Unix 纪元时间
- database - 如何构建我的时间序列 mongodb 文档和条目
- ios - iOS 14:允许位置访问 | 始终找不到菜单
- node.js - 无法使用一个可读流写入 Node JS 中的两个不同目标