Object.assign只能实现浅拷贝,深拷贝需手动递归判断类型并处理:null/基本类型直接返回,Date/RegExp等特殊对象单独克隆,数组和普通对象用Object.assign创建新容器后递归复制属性。

直接用 Object.assign 只能实现浅拷贝,它不会递归处理嵌套对象。要实现深拷贝,需手动递归遍历对象的每个属性,对引用类型(如对象、数组)继续调用拷贝函数,而基础类型(字符串、数字、布尔等)直接赋值。
核心思路:判断类型 + 递归复制
不能只靠 Object.assign,它只是工具之一——用于合并属性,但不负责递归逻辑。真正的深拷贝由你自己控制:遇到普通对象或数组就递归,其他类型(null、基本类型、Date、RegExp 等)需单独处理。
- 先判断是否为 null 或非对象(如 string、number、boolean、undefined),直接返回
- 再判断是否为 Date、RegExp 等特殊对象,做针对性克隆
- 如果是普通对象或数组,用
Object.assign创建新容器,再递归复制所有可枚举自有属性
基础版本(支持普通对象和数组)
下面是一个简洁可用的递归深拷贝函数,用 Object.assign 搭配 Array.isArray 和 typeof 判断:
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
let copy = Array.isArray(obj) ? [] : {};
Object.assign(copy, obj);
for (let key in copy) {
if (copy.hasOwnProperty(key)) {
copy[key] = deepClone(copy[key]);
}
}
return copy;
}
说明:Object.assign(copy, obj) 把源对象的可枚举属性“一层”复制到新对象中,之后再对每个值递归处理。注意这里没处理 Date、RegExp、Map、Set 等,仅适用于纯数据对象和数组。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
增强版:处理常见内置类型
实际项目中常遇到 Date、RegExp、甚至循环引用。下面补充关键类型判断(仍保持递归结构):
- Date →
new Date(obj.getTime()) - RegExp →
new RegExp(obj)(会丢失 flags,可用obj.source和obj.flags构造) - Array / Object → 继续递归
- 其他(如 Map、Set)需额外扩展,原生
Object.assign不适用,得手动遍历
例如 Date 处理:
if (obj instanceof Date) return new Date(obj.getTime());
注意事项与替代建议
递归 + Object.assign 是理解原理的好方式,但生产环境更推荐:
- 使用成熟的库如 lodash 的
_.cloneDeep(已处理循环引用、各种类型、性能优化) - JSON 方法(
JSON.parse(JSON.stringify(obj)))简单但丢失函数、undefined、Symbol、Date 对象等 - ES2022+ 的
structuredClone(现代浏览器支持,天然支持 Map/Set/Date/RegExp,且处理循环引用)
自己手写时务必加循环引用检测(用 WeakMap 记录已拷贝对象),否则递归会栈溢出。

















