扩展运算符{...obj}可实现对象浅拷贝,仅复制第一层可枚举属性,基础类型值被复制,引用类型仍共享内存;无法处理嵌套对象、不可枚举属性、symbol键及getter/setter。

JavaScript 中扩展运算符(...)可以快速实现对象的浅拷贝,但需注意它只复制第一层属性,嵌套对象仍共享引用。
扩展运算符如何进行浅拷贝
使用 {...obj} 语法,会将原对象自身可枚举的、非继承的属性逐个复制到新对象中,生成一个新对象实例。
- 新对象与原对象内存地址不同,修改新对象顶层属性不会影响原对象
- 若原对象某属性值是引用类型(如数组、对象、函数),该属性在新对象中仍指向同一内存地址
- 不可枚举属性(如通过 Object.defineProperty 设置的 enumerable: false)和原型链上的属性不会被复制
实际用法示例
假设有一个对象:
const original = { a: 1, b: { c: 2 } };用扩展运算符拷贝:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
此时:
- copy.a = 10 不会影响 original.a
- copy.b.c = 3 会同步改变 original.b.c(因为 b 是引用类型,未被深拷贝)
与其他浅拷贝方式对比
扩展运算符效果等价于 Object.assign({}, obj),都是浅拷贝。区别在于:
- 扩展运算符更简洁,语义更清晰,且支持解构时合并多个对象:{...a, ...b}
- 两者都不处理 Symbol 属性(除非显式展开:{ ...obj, ...{ [sym]: obj[sym] } })
- 都不能拷贝访问器属性(get/set),只会执行取值后复制结果值
什么情况下不适合用扩展运算符拷贝
当对象结构较深或含函数、正则、日期、Map/Set 等特殊对象时,扩展运算符无法正确复制其行为或类型。
- 例如:const obj = { date: new Date() }; → {...obj} 得到的是一个普通对象,date 属性仍是 Date 实例,但若涉及序列化或需要保持构造器信息,需额外处理
- 遇到嵌套对象需独立副本时,应配合递归或使用 structuredClone()(现代环境)或第三方库(如 Lodash 的 cloneDeep)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










