You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript数组克隆问题:修改克隆数组时原数组同步变更

JavaScript数组克隆后修改对象导致原数组变化的问题解决

你遇到的问题是:用扩展运算符克隆数组后,修改克隆数组中的对象属性,原数组也跟着发生了变化。这是因为你用的是浅拷贝,并没有真正复制数组里的对象。

你的示例代码

a = [];
a[0]    = {};
a[0].team = "Arsenal";
    
a[1]    = {};
a[1].team = "Chelsea";

a[2]    = {};
a[2].team = "West Ham";

function change_team(d, club){
    d[1].team = club;
    return d;
};

b = [...a]; // 克隆数组a
change_team(b, "spurs");

// 期望输出:Arsenal, Chelsea, West Ham;
for(n=0; n<a.length; n++){
    console.log(n+"] "+a[n].team);
};

// 期望输出:Arsenal, Spurs, West Ham;
for(n=0; n<a.length; n++){
    console.log(n+"] "+b[n].team);
};

问题原因

扩展运算符[...a]属于浅拷贝:它只会复制数组本身的结构,但数组里的每个元素都是对象的引用。也就是说,a[1]和b[1]指向的是同一个内存地址里的对象,修改b[1].team本质上是修改这个共享对象的属性,所以原数组a里的对应值也会跟着改变。

解决方案

要解决这个问题,需要对数组进行深拷贝,也就是连数组里的对象也一起复制一份新的。

方法1:使用structuredClone(推荐,现代环境支持)

structuredClone是浏览器和Node.js都支持的原生深拷贝方法,能处理大多数数据类型:

b = structuredClone(a); // 深拷贝数组a
change_team(b, "spurs");

方法2:使用JSON序列化(适合无特殊数据的场景)

如果数组里没有函数、undefined、循环引用这类JSON不支持的内容,可以用这种方法:

b = JSON.parse(JSON.stringify(a)); // 深拷贝数组a
change_team(b, "spurs");

方法3:手动遍历克隆每个对象

如果需要更灵活的控制,可以手动遍历数组,逐个克隆对象:

// 克隆数组并逐个复制对象
b = a.map(item => ({...item}));
change_team(b, "spurs");

用以上任意一种方法替换原来的b = [...a],修改克隆数组里的对象属性时,原数组就不会再被影响了。

内容的提问来源于stack exchange,提问作者Powl_London

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:57:39