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

如何在数组内对象值变更前存储其值?浅拷贝失效咨询

如何在修改数组中对象前存储原始值

这问题的核心在于你用了浅拷贝(slice就是干这个的),而数组里的对象是引用类型——简单说就是arr[2]和newA[2]其实指向内存里同一个对象,你改原数组里的对象属性,拷贝后的数组自然会跟着变。下面给你几种靠谱的解决方案:

方法1:JSON序列化/反序列化(简单场景首选)

这是最快速的深拷贝方式,适合对象里没有函数、undefined、循环引用这类特殊值的情况:

var arr = [0,0,{x:0,y:0}];
// 用JSON做深拷贝
var newA = JSON.parse(JSON.stringify(arr));
// 修改原数组对象的属性
arr[2].x =2;
arr[2].y =2;
console.log(newA); // 输出 [0,0,{x:0,y:0}],完美保留原始值

缺点:如果你的对象里包含函数、Symbol、循环引用,这种方法会丢失这些数据,所以要根据场景用。

方法2:手动递归深拷贝(自定义需求)

如果需要处理复杂对象(比如带函数、特殊类型),可以自己写一个递归拷贝函数,精准控制拷贝逻辑:

function deepCopy(target) {
  // 非对象或null直接返回原值
  if (typeof target !== 'object' || target === null) {
    return target;
  }
  // 判断是数组还是对象,初始化拷贝容器
  const copy = Array.isArray(target) ? [] : {};
  // 遍历所有自有属性,递归拷贝
  for (const key in target) {
    if (target.hasOwnProperty(key)) {
      copy[key] = deepCopy(target[key]);
    }
  }
  return copy;
}

var arr = [0,0,{x:0,y:0}];
var newA = deepCopy(arr);
arr[2].x =2;
arr[2].y =2;
console.log(newA); // 同样输出 [0,0,{x:0,y:0}]

这种方式灵活性最高,你可以根据需要扩展(比如处理Date、RegExp等特殊对象)。

方法3:原生structuredClone(现代环境推荐)

现代浏览器和Node.js都支持原生的structuredClone API,它能处理大部分类型,包括循环引用、Date、RegExp这些,比JSON方法更强大:

var arr = [0,0,{x:0,y:0}];
var newA = structuredClone(arr);
arr[2].x =2;
arr[2].y =2;
console.log(newA); // 还是保留原始值的数组

优点:原生支持,不用自己写代码,兼容性也不错(除了非常旧的浏览器)。

总结一下:如果你的对象结构简单,用JSON方法最省事;如果是现代环境,直接上structuredClone;需要自定义逻辑就用递归深拷贝。

内容的提问来源于stack exchange,提问作者KT-mongo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:43:40