简体   繁体   English

为什么通过 map 运行时使用扩展运算符的数组副本会修改原始数组?

[英]Why does the copy of an array using the spread operator when run through map modify the original array?

  1. Why does the copy of an array using the spread operator when run through map modify the original array?为什么通过 map 运行时使用扩展运算符的数组副本会修改原始数组?

  2. What should i do here to not mutate the original array?我应该怎么做才能不改变原始数组?

 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 "")

The spread operator creates shallow copy of the array.扩展运算符创建数组的浅拷贝。 In other words, you create a new array with references to the same objects.换句话说,您创建了一个引用相同对象的新数组。 So when you modify those objects, the changes are reflected in the original array.因此,当您修改这些对象时,更改会反映在原始数组中。

In general, when you need copy an array, you should consider making a deep copy.一般来说,当你需要复制一个数组时,你应该考虑做一个深拷贝。 However, in this case, you just need to use map() correctly.但是,在这种情况下,您只需要正确使用map()即可。 map() creates a new array, so it can make the modified copy for you directly: map()创建一个新数组,因此它可以直接为您制作修改后的副本:

const copyProps = props.map(el => {
        return {
            ...el,
            value: data[el.name] || '',
        }
});

Here I copy each object using the spread operator.在这里,我使用扩展运算符复制每个 object。 This means the resulting array has its own references of objects.这意味着生成的数组有自己的对象引用。 This has the same caveat as your original solution: this is a shallow copy.这与您的原始解决方案具有相同的警告:这是一个浅拷贝。 For your example data, it is fine because all values and keys are strings.对于您的示例数据,这很好,因为所有值和键都是字符串。 However, if your real data is more deeply nested with more arrays and objects, you will encounter the same problem.但是,如果您的真实数据与更多 arrays 和对象嵌套得更深,您将遇到同样的问题。

Both arrays and objects are passed by reference, so when you spread an array you create new array but fill it with references to original objects and when you modify those objects in the new array you still modify the same data in memory that is referenced in both arrays. arrays 和对象都是通过引用传递的,因此,当您传播数组时,您会创建新数组,但会用对原始对象的引用填充它,当您修改新数组中的这些对象时,您仍然会修改 memory 中引用的相同数据arrays。

Also map method will always return new array so in this case you only need to clone objects and since here you do not have deeply nested objects you can use object spread syntax.此外,map 方法将始终返回新数组,因此在这种情况下您只需要克隆对象,并且由于此处没有深度嵌套的对象,您可以使用 object 扩展语法。

 const data = { hello: "10" }; const prop = [{ name: "hello", color: "red", value: "" }] const copyProp = prop.map(el => ({...el, value: data[el.name] || '' })) console.log(copyProp) console.log(prop)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM