如你所知,有多种方法可以复制数组而无需复制引用,我注意到了
如果你有以下数组:
const x = [{age:25},{age:15}];
并且您需要使用扩展语法复制该数组,如此
const z = [...x];
更新z数组后,它将更新器官数组
z[0].age = 50
但是如果你使用像这样的Json解析器复制数组
const z = JSON.parse(JSON.stringify(x));
你不会面对这个问题,也不知道为什么会发生这种情况。
提前致谢。
答案 0 :(得分:2)
{age:25}
是一个对象。在第一种情况下复制数组的内容时,克隆该数组,但该数组包含对象的引用;然后,克隆的数组包含相同的引用。因此,当您更改第一个对象时,您还更改了第二个对象 - 因为它们是同一个对象,而不仅仅是一个相似的对象。
作为类比:杰克和梅格属于DnD俱乐部。然后形成一个动漫俱乐部,来自DnD俱乐部的每个人也加入了动漫俱乐部。如果动漫俱乐部的每个人都获得动漫俱乐部会员卡,那么DnD俱乐部(杰克和梅格)的人是否有动漫会员卡?为什么呢?
当您浏览JSON时,您会创建看起来像原始对象的新对象,但它们不是同一个对象。杰克和梅格加入了DnD俱乐部。动漫俱乐部开放,他们各自的同卵双胞胎Joe和Peg加入了动漫俱乐部。如果乔和佩格获得动漫俱乐部会员卡,杰克和梅格将不会有一张。
答案 1 :(得分:1)
您正在改变数组中的对象,该对象仍具有相同的引用 数组传播只会执行浅复制,它仍然会对其中的对象使用相同的引用。
您可以在数组上使用Array.prototype.map
并使用object spread syntax which is a proposal in stage 3返回对象的新副本(浅拷贝):
const z = x.map(o => ({...o}));
运行示例:
const x = [{age:25},{age:15}];
const z = x.map(o => ({...o}));
z[0].age = 50
console.log(x);
答案 2 :(得分:0)
这不是一个奇怪的问题,这只是对象的工作方式。
JSON.stringify(x)
以字符串格式创建对象的副本,完全断开对原始对象的引用( x ),然后字符串是使用JSON.parse
通过使用[...x]
,您只需在另一个数据结构中存储对象及其属性的引用。这就是为什么虽然它们似乎在改变不同的东西,因为它们是不同的变量,但它们只不过是对内存中相同位置的引用。对该位置的数据进行任何更改,而不是变量。它们共享相同的数据池。