浅拷贝只复制顶层结构,嵌套对象共享引用;深拷贝递归复制所有层级,完全独立互不影响。核心差异在于是否切断引用链,浅拷贝修改嵌套内容会同步影响原对象,深拷贝则不会。

浅拷贝和深拷贝的核心差异在于:是否真正切断引用链。处理复杂对象时,数据“看似独立却意外联动”,往往就是浅拷贝在底层悄悄共享了内存地址——尤其是嵌套对象、数组或类实例中存在引用类型字段时。
浅拷贝只复制第一层,引用类型仍共用同一块内存
比如一个对象包含数组或子对象:
let source = { a: 1, b: [2, 3], c: { d: 4 } };
let copy = Object.assign({}, source);
此时 copy.b 和 source.b 指向同一个数组,copy.c 和 source.c 指向同一个对象。修改 copy.b.push(5) 或 copy.c.d = 99,原始 source 会同步变化。
常见浅拷贝方法包括:
• Object.assign()
• 展开运算符({...obj}、[...arr])
• Array.prototype.slice()、concat()、Array.from()
深拷贝递归复制全部层级,彻底隔离引用关系
深拷贝会逐层检查每个属性值的类型:遇到基本类型直接赋值,遇到对象或数组则新建结构并继续递归。最终生成一个与原对象完全无关的新内存区域。
例如:
let deepCopy = JSON.parse(JSON.stringify(source));
这时 deepCopy.b 是全新数组,deepCopy.c 是全新对象,修改它们不会影响 source。
但要注意该方式的限制:
• 丢弃 function、undefined、Symbol、Date、RegExp
• 无法处理循环引用(如 obj.self = obj)
• Date 变成字符串,NaN 变成 null
业务中典型的数据一致性问题场景
这类问题常出现在以下环节:
• 分类列表共用同一份接口返回数据,但各分类页需独立编辑子项(如专科中心、专家团队都源自 this.centerList)
• 表单预填 + 多步编辑,中途切换导致上一步状态被覆盖
• Vuex/Pinia 中 state 被组件直接修改,引发其他组件视图错乱
• 图表配置项嵌套深层对象,A 图表改颜色后 B 图表也变色
根本原因都是:多个变量/属性指向了同一引用对象,而开发者误以为已“复制出一份”。
安全选择策略:按需选用,不盲目深拷贝
• 单层简单数据(纯数字、字符串、布尔值)→ 浅拷贝足够,性能更好
• 多层嵌套且后续只读 → 浅拷贝 + Object.freeze() 防误改
• 需独立修改任意层级 → 用 structuredClone()(现代浏览器支持)、lodash.cloneDeep() 或手写带 WeakMap 的递归深拷贝(防循环引用)
• 含函数、日期、正则等特殊值 → 必须手写或使用成熟库,避免 JSON 方案
关键判断点:不是看“对象多不多”,而是看“会不会有人改它的子属性”。只要有一处修改嵌套内容,就必须深拷贝。










