javascript - 为什么通过 map 运行时使用扩展运算符的数组副本会修改原始数组?
问题描述
为什么通过 map 运行时使用扩展运算符的数组副本会修改原始数组?
我应该怎么做才能不改变原始数组?
const data = {hello : "10"};
const prop = [{name : "hello", color: "red", value : ""}]
const copyProp = [ ...prop ]
copyProp.map(el => {
el.value = data[el.name] || ""
return el
}) //
console.log(copyProp === prop) // -> false
console.log(copyProp) // -> value: 10
console.log(prop) // -> Value: 10 (Should still be "")
解决方案
扩展运算符创建数组的浅拷贝。换句话说,您创建了一个引用相同对象的新数组。因此,当您修改这些对象时,更改会反映在原始数组中。
一般来说,当你需要复制一个数组时,你应该考虑做一个深拷贝。但是,在这种情况下,您只需要map()
正确使用即可。map()
创建一个新数组,因此它可以直接为您制作修改后的副本:
const copyProps = props.map(el => {
return {
...el,
value: data[el.name] || '',
}
});
在这里,我使用扩展运算符复制每个对象。这意味着生成的数组有自己的对象引用。这与您的原始解决方案具有相同的警告:这是一个浅拷贝。对于您的示例数据,这很好,因为所有值和键都是字符串。但是,如果您的真实数据与更多的数组和对象嵌套得更深,您将遇到同样的问题。
推荐阅读
- python - 来自不同设备的 Python Socket 连接不起作用
- python - 如何在 Python 中为不和谐机器人修复 RuntimeError?
- twitter-bootstrap - 以特定顺序排列的 Bootstrap4 卡
- clojure - clojure 将集合拆分为越来越大的块
- python - 在python数学中将相量计算转换为复数
- javascript - 传播操作员在反应 js 中给出错误,说意外的令牌
- unix - /usr/xpg4/bin/grep -q [^0-9] 并不总是按预期工作
- c# - GameObject.Find 在 DontDestroyOnLoad 中对 Player 不起作用
- java - 它没有显示任何错误,但编译器只是继续加载或显示 [object object]
- c# - 使用另一个类名反序列化