对象数组浅拷贝危险在于新数组虽独立,但内部对象仍共享内存地址,导致修改副本对象属性时原数组同步变化;危险操作包括扩展运算符、slice()、array.from()等仅复制数组外壳的方法;安全方案需按层级选择:一维对象用map+展开语法,复杂结构用structuredclone()或lodash clonedeep()。

对象数组浅拷贝的危险性,核心在于“表面独立、底层共享”——新数组是新的,但里面的每个对象仍和原数组指向同一内存地址。改副本里的对象属性,原数组立刻同步变化,看似隔离实则联动。
为什么对象数组浅拷贝特别容易踩坑
因为数组本身被复制了(新地址),但每个元素(比如 {name: "Alice", age: 30})只是引用被复制,不是对象被重建。这导致:
- 调用
arr2[0].name = "Bob",arr1[0].name也变成 "Bob" - 用
map更新某个对象字段,原始数组对应项同步变 - 把数组传给函数后修改内部对象,调用方数据意外污染
哪些操作属于危险的浅拷贝
以下写法都只复制数组外壳,不复制内部对象:
const copy = [...original]const copy = original.slice()const copy = Array.from(original)const copy = original.concat()const copy = Object.assign([], original)
它们对 [1, "a", true] 安全,但对 [{x: 1}, {y: 2}] 就失效。
安全替代方案:按需选择深拷贝层级
✅ 一维对象数组(元素全是普通对象,无嵌套):
用 map + 展开语法,轻量且语义明确:
const copy = original.map(item => ({...item}));
✅ 含嵌套对象、Date、Map、Set 或循环引用:
优先用原生 structuredClone()(Chrome 98+/Firefox 94+/Safari 16.4+/Node.js 18.16+):
const copy = structuredClone(original);
✅ 需兼容老旧环境(如 IE 或 Node.js :
使用 Lodash 的 _.cloneDeep(),成熟稳定,边界处理完善。
额外提醒:别忽略可变嵌套字段
即使你深拷贝了数组,如果对象里还有可变引用(比如 user.profile.address = new Address()),而 Address 类没实现深拷贝,那风险仍在。深拷贝必须穿透每一层——数组 → 对象 → 对象属性 → 属性中的集合或子对象。











