扩展运算符{...obj}仅浅拷贝第一层属性,基础类型值被复制,引用类型仍共享内存;无法处理嵌套对象、不可枚举属性、symbol键及getter/setter;深拷贝需用structuredclone或json.parse(json.stringify())等方案。

JavaScript 中用扩展运算符 {...obj} 可以快速实现对象的浅拷贝,但要注意它只复制第一层属性,嵌套对象仍共享引用。
扩展运算符怎么实现浅拷贝
扩展运算符会把源对象的所有可枚举自身属性(不含原型链上的)展开,生成一个新对象。这个过程不改变原对象,返回的是一个新对象实例。
- 语法简洁:
const copy = {...original}; - 仅拷贝一层:基础类型值(如字符串、数字)被复制,引用类型(如数组、对象)仍指向原内存地址
- 不能拷贝不可枚举属性、Symbol 属性(除非显式列出)、getter/setter(会执行 getter 得到返回值,而非保留访问器本身)
常见陷阱:嵌套对象没被真正复制
如果原对象里有嵌套对象或数组,扩展运算符不会递归处理,新对象中的嵌套结构仍与原对象共享同一引用。
例如:
const user = { name: 'Alice', info: { age: 30 } };const cloned = { ...user };
cloned.info.age = 31;
console.log(user.info.age); // 输出 31 —— 原对象也被改了
什么时候适合用扩展运算符拷贝
适用于结构扁平、确定不含深层嵌套的对象,或者你只需要第一层隔离的场景。
- 合并多个配置对象:
{...defaults, ...overrides} - 更新部分字段同时保留其余:
{...obj, name: 'New Name'} - 函数参数解构后重新组装:
const { id, ...rest } = data; return { ...rest, status: 'done' };
想深拷贝怎么办
扩展运算符做不到深拷贝。需要深拷贝时,可考虑:
- 结构简单且无函数、undefined、Date 等特殊值:用
JSON.parse(JSON.stringify(obj))(注意局限性) - 更健壮方案:使用
structuredClone()(现代浏览器支持,能处理 Map、Set、Date 等) - 复杂需求:引入 Lodash 的
_.cloneDeep()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











