根本区别在于赋值使变量共享同一堆内存,浅拷贝仅第一层属性独立、嵌套引用仍共享;赋值如let b = a是地址复制,修改任一对象另一方同步变化;浅拷贝如{...a}对基本类型值复制,对引用类型仍共享原堆内存。

根本区别在于:赋值是让两个变量共享同一块堆内存,而浅拷贝是创建一个新对象,只在第一层属性上“断开连接”——基本类型值被真正复制,引用类型值仍共享原堆内存。
赋值:只是起了个新名字
赋值操作(let b = a)不创建新对象,只是把栈中存储的地址复制一份。a 和 b 完全指向堆里的同一个对象。改任何一个,另一个立刻同步变化,因为它们操作的是同一块数据。
- 比如
let obj1 = {x: 1, y: {z: 2}};,再写let obj2 = obj1;,obj1 和 obj2 就是同一个对象的两个别名 - 执行
obj2.x = 99,obj1.x 也变成 99;执行obj2.y.z = 88,obj1.y.z 同样变成 88
浅拷贝:第一层“分家”,深层仍共用
浅拷贝(如 Object.assign({}, a)、[...a]、{...a})会新建一个对象或数组,把原对象第一层的属性值逐个拷贝过去。
- 对基本类型(string/number/boolean等),拷贝的是实际值,互不影响
- 对引用类型(object/array等),拷贝的是栈里存的那个地址,不是堆里的内容——所以新旧对象的嵌套对象仍指向同一块堆内存
- 例如
let a = {p: 1, q: [10, 20]},let b = {...a}后:b.p = 99不影响 a.p,但b.q.push(30)会让 a.q 也变成[10, 20, 30]
关键判断标准:修改嵌套对象时是否联动
最直接的检验方式是操作第二层引用值:
- 赋值后改
a.nested.prop→b.nested.prop一定变 → 是赋值 - 浅拷贝后改
a.nested.prop→b.nested.prop也变 → 说明嵌套部分没被复制,符合浅拷贝特征 - 只有深拷贝后,改任意层级都不影响对方
为什么这个区别很重要
在状态管理(如 Redux)、响应式系统(Vue 的 reactive)、不可变更新(React)中,误用赋值或浅拷贝会导致意外的副作用:UI 不更新、依赖收集失效、状态污染。你不是在复制数据,是在决定数据流的边界和生命周期。


















