展开运算符(...)可简洁实现对象浅拷贝,但仅复制第一层属性,嵌套对象仍共享引用;不复制不可枚举属性、原型链及Symbol键;深拷贝需用JSON.parse(JSON.stringify())、Lodash.cloneDeep()或structuredClone()。

展开运算符(...)是 JavaScript 中实现对象浅拷贝最简洁的方式之一,但它只复制第一层属性,对嵌套对象或数组无效。
展开运算符的基本语法
使用 {...obj} 可以快速创建一个新对象,其自有可枚举属性被逐个复制:
示例:
const original = { a: 1, b: 2, c: { d: 3 } };
const copy = { ...original };
console.log(copy); // { a: 1, b: 2, c: { d: 3 } }
console.log(copy === original); // false(新对象)
console.log(copy.c === original.c); // true(引用未变)
它只能做浅拷贝
所有基础类型(字符串、数字、布尔值等)会被真正复制;但对象、数组、函数等引用类型,只是把指针复制过去,原对象与拷贝共享同一内存地址。
立即学习“Java免费学习笔记(深入)”;
- 修改
copy.c.d会影响original.c.d - 给
copy新增属性(如copy.e = 5)不会影响original - 删除
copy.b也不会影响original.b
不支持不可枚举属性和原型链
展开运算符只遍历对象自身的、可枚举的属性(即 Object.keys() 能拿到的),以下内容不会被复制:
- 通过
Object.defineProperty()设置的enumerable: false属性 - 原型上的方法或属性(如
toString、自定义的prototype.xxx) - Symbol 类型的键(除非显式列出)
替代方案与补充建议
若需深拷贝,不能依赖展开运算符,应考虑:
-
JSON.parse(JSON.stringify(obj))(仅适用于纯数据,不支持函数、undefined、Date、RegExp 等) - Lodash 的
_.cloneDeep() - 结构较简单时,手动递归实现或用
structuredClone()(现代浏览器支持)
若只需浅拷贝且要包含 Symbol 或不可枚举属性,可用 Object.getOwnPropertyDescriptors() 配合 Object.defineProperties()。


















