浅拷贝在多层嵌套对象解构中失效,因其仅复制第一层属性值或引用,嵌套引用类型仍共享内存地址;修改深层属性会导致原对象与拷贝对象同步变化。

浅拷贝在多层嵌套对象解构中会失效,是因为它只复制第一层属性的值或引用,对嵌套的引用类型(如对象、数组)仍保留原地址。一旦修改深层属性,原对象和拷贝对象会同步变化。
为什么解构赋值只是浅拷贝
ES6 解构赋值(如 const newObj = { ...obj })或 Object.assign() 本质是遍历对象自有可枚举属性,逐个赋值。如果某个属性值是引用类型(比如 jobs: { first: 'FE' }),拷贝进去的仍是该子对象的内存地址,不是新副本。
- 第一层属性(如 age: 1)是基本类型,拷贝的是实际值,互不影响
- 第二层及更深的属性(如 jobs.first)属于嵌套引用,拷贝的是指针,指向同一堆内存
- 因此 newObj.jobs === obj.jobs 为 true,改 newObj.jobs.first 就等于改原对象
常见“看似深拷贝”但实际失效的写法
这些方法常被误认为能处理嵌套结构,实则仅限一层:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- {...obj}:展开后只复制顶层键值,子对象仍共享
- Object.assign({}, obj):同上,不递归处理嵌套对象
- Array.slice() / [...arr]:对一维数组安全;若数组含对象(如 [{id: 1}]),元素仍被引用
- JSON.parse(JSON.stringify(obj)) 虽能深拷贝,但会丢失 function、undefined、Date、RegExp、Symbol 等类型
真正可靠的深拷贝方案
需确保每一层引用类型都创建独立副本:
- structuredClone()(推荐):现代浏览器支持(Chrome 98+、Firefox 94+、Safari 15.4+),能正确处理 Date、Map、Set、ArrayBuffer 等,且不丢失类型
- 递归实现:手动遍历对象/数组,对每个引用类型属性调用自身,适合学习原理或兼容旧环境
- Lodash _.cloneDeep():成熟稳定,覆盖边界情况多,适合生产环境
如何验证是否真的深拷贝成功
不能只看顶层是否相等,要测试深层嵌套属性的独立性:
- 修改拷贝对象的深层属性(如 copied.child.info.name = 'xxx')
- 检查原始对象对应路径是否未变(original.child.info.name !== 'xxx')
- 用 === 比较各层子对象,应全部返回 false
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










