如何在数组内对象值变更前存储其值?浅拷贝失效咨询
如何在修改数组中对象前存储原始值
这问题的核心在于你用了浅拷贝(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
相关产品推荐
相关产品推荐

