浅拷贝创建新对象但嵌套引用仍共享,修改嵌套对象或数组会同步影响原对象;验证方式是改副本嵌套属性后检查原对象是否变化,如b.y.z = 99导致a.y.z也变为99。

浅拷贝对引用类型属性只复制内存地址,不是复制数据本身,所以修改嵌套对象或数组时,新旧对象会互相影响。这是最常引发 bug 的地方,关键不在“有没有拷贝”,而在“改了嵌套内容会不会波及原对象”。
看顶层对象是否独立(先确认是不是真拷贝)
如果 obj2 = obj1,那根本没拷贝,只是起别名;obj1 === obj2 为 true。而浅拷贝必须满足:obj1 !== obj2(新对象已创建),但 obj1.nested === obj2.nested(嵌套引用仍相同)。常用方式如 {...obj1}、Object.assign({}, obj1) 都符合这个特征。
改嵌套字段,观察原对象是否同步变化
这是最直接的验证方法:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 设
const a = { x: 1, y: { z: 2 } } - 执行浅拷贝:
const b = { ...a } - 修改嵌套属性:
b.y.z = 99 - 此时
a.y.z也变成 99 —— 这就是副作用:共享堆内存导致意外联动
基本类型 vs 引用类型表现完全不同
同一拷贝操作下,两类属性行为割裂:
-
基本类型(如
x: 1):修改b.x不影响a.x,因为值被真正复制 -
引用类型(如
y: { z: 2 }):修改b.y.z或b.y.push(...)都会反映到a.y上,因指向同一块堆内存
常见误判场景
容易以为“用了扩展运算符就安全了”,其实不然:
-
JSON.parse(JSON.stringify(obj))看似深拷贝,但会丢函数、undefined、Symbol、Date、RegExp、循环引用等 -
structuredClone()是现代浏览器支持的真深拷贝,但 IE 不支持,Node.js 17+ 才可用 - 第三方库如 Lodash 的
cloneDeep()更稳妥,但引入额外体积
识别这个副作用不靠记忆规则,而靠动手验证:改一层、改嵌套、比相等性、查原始值。只要嵌套一动两边都变,就是浅拷贝在起作用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










