浅拷贝与深拷贝
1. 概念与区别
(1) 浅拷贝
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。
- 如果属性是基本类型,拷贝的就是基本类型的值。
- 如果属性是引用类型,拷贝的就是内存地址 (引用)。如果其中一个对象改变了这个地址,就会影响到另一个对象。
实现方式:
Object.assign- 展开运算符
... Array.prototype.slice()/concat()(针对数组)
(2) 深拷贝
将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
实现方式:
JSON.parse(JSON.stringify())(最简单,有缺陷)structuredClone(现代浏览器 API)- 手写递归 (最稳妥)
- 第三方库
lodash.cloneDeep
2. 浅拷贝实现方案
3. 深拷贝实现方案
(1) JSON 序列化
缺陷 (高频考点):
- 忽略 undefined 属性。
- 忽略 Symbol 属性。
- 忽略 function (会将函数变为 undefined 或者抛错)。
- Date 对象变为字符串。
- RegExp 对象变为
{}。 - 循环引用 会报错 (
Converting circular structure to JSON)。
(2) structuredClone (ES2022)
优点:解决了 JSON 方案的循环引用和大部分特殊类型丢失问题 (支持 Date, RegExp, Map, Set, ArrayBuffer 等)。 缺陷:
- 不支持 function (无法克隆函数)。
- 不支持 DOM 节点。
- 如果不兼容旧环境,需 polyfill。
(3) 手写递归 DeepClone
能够处理循环引用是一个关键加分项 (使用 WeakMap)。
4. 面试总结
- 浅拷贝:一层复制,引用共享。(
Object.assign,...) - 深拷贝:完全独立。(
JSON,structuredClone, 递归) - JSON 缺陷:忽略
undefined/symbol/function,不支持循环引用。 - 手写要点:递归 + 类型判断 +
WeakMap防循环引用。

