展开运算符...拷贝对象是浅拷贝,仅复制自身可枚举属性,不包括原型链、不可枚举属性和Symbol属性(除非显式处理);支持合并多个对象(后覆盖前)及结合解构剔除指定字段。

用展开运算符 ... 拷贝对象,本质是创建一个新对象,并把原对象的**自身可枚举属性**(不包括原型链上的属性)复制过去,属于浅拷贝。
基础写法:直接展开单个对象
最常见也最直观的方式:
const newObj = { ...oldObj };
这会把 oldObj 自身所有可枚举属性(Object.keys(oldObj) 能拿到的)复制到 newObj 中。注意:
– 原型链、不可枚举属性(如 Object.defineProperty 设置的 enumerable: false)、Symbol 属性(除非显式展开)都不会被拷贝;
– 如果属性值是引用类型(如数组、对象、函数),只复制其引用,不是深拷贝。
立即学习“Java免费学习笔记(深入)”;
合并多个对象:后覆盖前
展开运算符支持一次展开多个对象,后面的属性会覆盖前面同名属性:
const merged = { ...obj1, ...obj2, ...obj3 };
等价于按顺序逐个拷贝属性,适合做配置合并或默认值填充。例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const defaults = { theme: 'light', fontSize: 14 };const userConfig = { fontSize: 16 };const finalConfig = { ...defaults, ...userConfig }; // { theme: 'light', fontSize: 16 }
排除/筛选属性:结合解构与展开
想拷贝时跳过某些字段?可用解构 + 展开组合实现“剔除”效果:
const { password, token, ...safeUser } = user;// safeUser 是 user 的浅拷贝,不含 password 和 token
原理是:解构出不需要的字段,再用 ... 收集剩余属性到新对象中。注意:
– 只能剔除已知键名,不适用于动态过滤;
– 若原对象有嵌套对象,内部仍为引用,未做深处理。
补充说明:Symbol 属性和不可枚举属性需手动处理
展开运算符默认忽略 Symbol 键和不可枚举属性。如需包含 Symbol,必须显式展开:
const sym = Symbol('id');const obj = { a: 1, [sym]: 'secret' };const copy = { ...obj, [sym]: obj[sym] }; // 手动补上 Symbol 属性
对于不可枚举属性,需借助 Object.getOwnPropertyDescriptors() + Object.defineProperties(),此时展开运算符已不够用,应换用其他方式。

















