核心是理解“数据在哪、怎么连、改了谁会变”:值类型赋值复制真实数据,互不影响;引用类型赋值复制地址,共用同一对象;浅拷贝仅复制顶层,嵌套仍共享;深拷贝递归新建所有层级,完全独立。

学浅拷贝和深拷贝,核心不是背方法,而是理解“数据在哪、怎么连、改了谁会变”。只要抓住这个主线,所有方案自然就清晰了。
先搞懂底层:值类型 vs 引用类型
这是所有拷贝问题的起点:
- 值类型(string、number、boolean、null、undefined、symbol、bigint):变量里存的就是真实数据,赋值=复制一份新值,互不影响
- 引用类型(Object、Array、Date、RegExp、Map、Set、Function 等):变量里存的是内存地址,赋值=多给一把钥匙,开的是同一个房间
比如:const a = {x: 1}; const b = a; —— 这不是拷贝,是共用。改 b.x,a.x 立刻跟着变。
浅拷贝:只管第一层,嵌套还是连着的
它创建新对象,但只复制顶层属性。基本类型值被真正复制;引用类型值仍共享地址。
-
对象常用写法:
{...obj}、Object.assign({}, obj) -
数组常用写法:
[...arr]、arr.slice()、arr.concat()、Array.from(arr) -
关键验证法:修改拷贝后对象的嵌套属性(如
copy.nested.prop = 99),如果原对象也变了,那就是浅拷贝
⚠️ 注意:这些方法都不处理原型链、不拷贝不可枚举属性、对 null 或 undefined 入参行为也不一致。
深拷贝:彻底断开所有连接,各过各的
它递归遍历每一层,为每个引用类型都新建内存空间。改副本,原对象纹丝不动。
-
最简但有硬伤:
JSON.parse(JSON.stringify(obj))—— 快速有效,但会丢function、undefined、Symbol、Date(转成字符串)、RegExp、Map/Set,遇到循环引用直接报错 -
现代推荐首选:
structuredClone(obj)(Chrome 98+、Firefox 94+、Safari 15.4+ 支持)—— 原生、完整、安全,支持Map、Set、Date、RegExp、ArrayBuffer和循环引用 -
兼容性兜底方案:用
lodash.cloneDeep或手写递归 +WeakMap记录已克隆对象,防止循环引用死递归
实战判断口诀:三问定方案
写代码前快速自问:
- 数据结构是否简单?全是基础类型或一层对象 → 浅拷贝够用
- 有没有嵌套对象/数组?会不会在下游被修改?→ 必须深拷贝
- 环境是否支持
structuredClone?要不要兼容老浏览器?→ 决定用原生还是第三方库
别一上来就写递归,也别无脑上 JSON 方案。看场景,再选工具。


















