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

使用扩展运算符修改数组引用后仍受原对象影响的技术问题

问题分析与解决方案

我遇过不少类似的情况,核心问题其实出在浅拷贝和深拷贝的区别上——你的扩展运算符用的是浅拷贝,而实际代码里的数组元素大概率是引用类型(比如对象、嵌套数组),这就导致拷贝后的数组和原数组共享内部元素的引用,原数组修改内部元素时,拷贝数组也会跟着变。

为什么你的最小示例没问题?

你提供的示例里,数组元素是number这种基本类型,扩展运算符的浅拷贝完全够用:基本类型的值是直接复制的,拷贝后的数组和原数组各自持有独立的值,修改原数组的元素(比如替换整个数组为[1,2,4])不会影响拷贝数组。

实际代码出问题的原因

如果你的实际代码里,数组元素是引用类型(比如对象),情况就不一样了:

// 举个实际代码可能的例子
initialArrayThatChanges = [{ value: 1 }, { value: 2 }, { value: 3 }];
// 扩展运算符做浅拷贝,只复制数组的外层引用
initialArrayWithNoChanges = [...this.initialArrayThatChanges];

// 当你修改原数组里某个对象的属性时
this.initialArrayThatChanges[0].value = 100;
// 拷贝数组里的对应对象也会跟着变,因为它们引用的是同一个对象!
console.log(this.initialArrayWithNoChanges[0].value); // 输出100

这时候扩展运算符只解决了数组本身的引用问题,但内部的对象引用还是共享的,所以看起来“旧数组仍随初始对象变化”。

为什么JSON.parse(JSON.stringify(array))能解决?

这种方式是一种简单的深拷贝实现:它把整个数组(包括内部所有嵌套的对象)转换成JSON字符串,再重新解析成新的对象/数组。这个过程会重新创建所有层级的元素,彻底断开和原数组的引用关联,所以修改原数组不会影响拷贝后的数组。

更合适的解决方案

如果你的数组结构比较简单(比如只有一层对象),可以用map结合扩展运算符做一层拷贝:

initialArrayWithNoChanges = this.initialArrayThatChanges.map(item => ({ ...item }));

如果是多层嵌套的复杂结构,推荐:

  • 手动写递归拷贝函数,精确控制拷贝逻辑;
  • 使用成熟的第三方工具库(比如Lodash的_.cloneDeep方法),它能处理各种边缘情况(比如循环引用、特殊类型等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:19:09