扩展运算符仅能实现对象第一层浅拷贝,对嵌套对象仍共享引用;若需多层独立副本,应使用structuredclone()、json序列化或lodash的clonedeep()等深拷贝方法。

扩展运算符(...)本身只能实现对象的**第一层浅拷贝**,对嵌套对象(多层)无法自动递归拷贝。也就是说,它不能直接实现“多层对象的浅拷贝”——因为“浅拷贝”在定义上就只复制一层引用,深层属性仍共享。但如果你实际想做的是“让多层结构中每一层都独立(即深拷贝)”,那扩展运算符是不够的;而如果你只是想安全地合并/展开多层对象并控制拷贝层级,可以组合使用扩展运算符和其它方法。
扩展运算符只能浅拷贝第一层
看这个例子:
const obj = {
a: 1,
b: { c: 2, d: { e: 3 } }
};
const copy = { ...obj };
copy.a = 99;
copy.b.c = 99;
console.log(obj.a); // 1 → 独立
console.log(obj.b.c); // 99 → 共享!b 是引用,没被深拷贝
这里 {...obj} 只复制了 a 和 b 这两个属性的值,而 b 是个对象引用,所以 copy.b 和 obj.b 指向同一内存地址。
用扩展运算符 + 手动展开实现“指定层数”的拷贝
如果嵌套层级固定且较浅(比如两层),你可以手动对内层也用扩展运算符:
- 适合结构已知、层级少(如两层)、不想引入外部库的场景
- 本质仍是浅拷贝,只是你主动对每层做了展开
例如两层对象:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const obj = {
name: 'Alice',
profile: {
age: 30,
city: 'Beijing'
}
};
// 两层浅拷贝(手动展开第二层)
const copy = {
...obj,
profile: { ...obj.profile }
};
copy.profile.age = 31;
console.log(obj.profile.age); // 30 → 不受影响 ✅
三层及以上?扩展运算符就不够用了
三层需要写成:
const copy = {
...obj,
nested: {
...obj.nested,
deeper: { ...obj.nested.deeper }
}
};
这种写法很快变得冗长、易错、不可维护。此时应考虑:
- JSON 序列化反序列化:适用于纯数据对象(无函数、undefined、Symbol、Date、RegExp 等)
- structuredClone():现代浏览器支持(Chrome 98+、Firefox 94+),可处理 Map/Set/Date 等,是真正的深拷贝
-
Lodash 的
_.cloneDeep():兼容性好,功能全
例如:
// 安全的深拷贝(推荐用于多层) const copy = structuredClone(obj); // ✅ 支持多层、Date、Map 等 // 或 const copy = JSON.parse(JSON.stringify(obj)); // ⚠️ 仅限简单数据
小结:别指望扩展运算符“自动”处理多层
扩展运算符不是深拷贝工具,它的作用是展开可迭代对象或对象属性。所谓“多层浅拷贝”本身是个矛盾说法——浅拷贝只定义在第一层。你需要的是:
- 明确目标:是否真需要深拷贝?还是只需冻结某几层?
- 结构简单 → 手动展开(两层以内可行)
- 结构复杂或含特殊类型 → 用
structuredClone或成熟工具 - 避免误用
{...obj}后修改嵌套属性,以为原对象不受影响
理解这点,就能避开很多隐蔽的引用 bug。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










