深拷贝需递归复制对象所有层级。1. JSON.parse(JSON.stringify()) 快但不支持函数、循环引用等;2. 手写递归函数可处理 Date、RegExp 和循环引用;3. structuredClone() 原生支持多数类型且性能好,但兼容性有限;4. Lodash 的 _.cloneDeep() 最稳定,适合复杂场景。

JavaScript中实现对象的深拷贝,是开发中常见但容易出错的问题。浅拷贝只复制对象的第一层属性,而嵌套的对象或数组仍然共享引用。深拷贝则会递归复制所有层级,确保新对象与原对象完全独立。下面介绍几种实用且可靠的深拷贝方法。
1. 使用 JSON.parse(JSON.stringify())
这是最简单快捷的深拷贝方式,适用于大多数纯数据对象。
注意:这种方法有明显限制:- 无法处理函数、undefined、Symbol等非序列化值
- 会忽略不可枚举属性和原型链上的属性
- 循环引用会导致报错
- Date对象会被转为字符串
示例:
const obj = { name: "Alice", info: { age: 25 } };
const copied = JSON.parse(JSON.stringify(obj));
obj.info.age = 30;
console.log(copied.info.age); // 25,成功隔离
2. 手写递归深拷贝函数
自己实现一个兼容性更好的 deepClone 函数,可以处理更多类型和边界情况。
立即学习“Java免费学习笔记(深入)”;
基本思路:判断数据类型,对对象和数组递归复制,其他类型直接返回。
function deepClone(obj, visited = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
// 处理日期
if (obj instanceof Date) return new Date(obj);
// 处理正则
if (obj instanceof RegExp) return new RegExp(obj);
// 防止循环引用
if (visited.has(obj)) return visited.get(obj);
// 保留构造函数信息
const clone = Array.isArray(obj) ? [] : {};
visited.set(obj, clone);
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
clone[key] = deepClone(obj[key], visited);
}
}
return clone;
}
这个版本支持循环引用(使用 WeakMap),也能正确处理 Date 和 RegExp 类型。
3. 利用结构化克隆算法(浏览器 API)
现代浏览器提供 structuredClone() 方法,原生支持深拷贝,且支持更多类型。
const original = { date: new Date(), nested: { count: 1 } };
const cloned = structuredClone(original);
优点:
- 原生支持,性能好
- 支持 Date、RegExp、Map、Set、ArrayBuffer 等
- 自动处理循环引用
4. 使用第三方库(如 Lodash)
Lodash 的 _.cloneDeep() 是最稳定的解决方案之一。
const _ = require('lodash');
const obj = { a: 1, b: { c: 2 } };
const copied = _.cloneDeep(obj);
优势:
- 兼容性极好,支持各种复杂类型
- 经过大量测试,稳定性高
- 处理循环引用无压力
如果项目已引入 Lodash,推荐直接使用。
基本上就这些主流方法。选择哪种取决于你的使用场景:简单数据用 JSON 方式最快,需要兼容性选 Lodash,现代项目可尝试 structuredClone,自定义需求可手写递归函数。关键是理解每种方法的边界和限制。










