浅拷贝只复制对象第一层属性,嵌套的引用类型仍共享内存地址。基本类型值被复制,引用类型地址被复制,修改嵌套属性会影响原对象;深拷贝才能完全隔离各层级。

因为浅拷贝只复制第一层属性的值,对嵌套的引用类型(比如对象、数组)只是复制了内存地址,新旧对象仍指向堆中同一块数据。
浅拷贝只动“表皮”,不动“里子”
JavaScript 中,基本类型(如 number、string)存于栈,赋值即复制值;而引用类型(如 object、array)本身存在堆里,变量里存的是指向堆的地址。浅拷贝就是把这串地址原样抄一份——外表是新对象,内里还是老地方。
-
对象第一层属性是基本类型:比如
name: '张三',拷贝后改copy.name不会影响原对象 -
对象第一层属性是引用类型:比如
address: { city: '杭州' },拷贝后copy.address和original.address指向同一个对象,改copy.address.city就等于直接改原对象里的city
常见浅拷贝操作都会这样
这些写法看似“新建”,实则只隔离了最外层:
-
Object.assign({}, obj)—— 只复制可枚举自有属性,obj.nested的引用照搬 -
{...obj}或[...arr]—— 展开语法同理,嵌套对象/数组不递归 -
arr.slice()、Array.from(arr)、[].concat(arr)—— 对含对象的数组完全无效
一个直观例子
运行这段代码就能看到联动效果:
const user = { name: '张三', address: { city: '杭州' } };
const copy = { ...user };
copy.address.city = '滨江区';
console.log(user.address.city); // 输出 '滨江区'
这里 copy 是新对象,但 copy.address 和 user.address 是同一个对象实例,改它的属性,谁都躲不掉。
怎么避免这种影响
关键看你要不要改嵌套内容:
- 确认后续只读或只改顶层字段 → 浅拷贝够用
- 需要独立修改任意层级 → 必须深拷贝:
structuredClone(obj)(现代首选)、JSON.parse(JSON.stringify(obj))(简单结构可用,但丢函数/undefined/循环引用)、或_.cloneDeep()(兼容性好)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











