javascript递归深拷贝需先判断类型:基础类型直接返回,引用类型用weakmap防循环引用,数组、date、regexp等特殊类型分别处理,对象则遍历属性递归克隆。

JavaScript 中用递归实现多维数组的深拷贝,核心是判断每个元素是否为引用类型(如数组、对象),再对其递归处理;基础类型直接赋值,引用类型则新建结构并继续递归。
识别并递归处理嵌套结构
递归函数需先判断当前值是否为数组或普通对象。如果是数组,创建新空数组,遍历原数组每一项,对每项调用自身;如果是对象(且非 null、非数组),创建新空对象,遍历 key,对每个 value 递归克隆。
- 用 Array.isArray() 准确区分数组和类数组
- 避免用
typeof obj === 'object'判断——它会把null、数组、日期等都判为 object - 对
null要单独处理,否则递归时会报错或误判
处理常见引用类型边界情况
纯递归深拷贝默认只覆盖数组和普通对象。若数据中含 Date、RegExp、Map、Set 等,需额外分支处理:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
Date:用
new Date(obj.getTime())克隆 -
RegExp:用
new RegExp(obj),注意 flags(如g、i)需提取 - Map / Set:新建实例,遍历键值对或元素,递归克隆内容
- 遇到函数、Symbol、undefined 等,通常选择跳过或原样保留(深拷贝一般不复制函数)
防止循环引用导致栈溢出
若对象内部存在自引用(如 a.b = a),纯递归会无限深入。解决方法是维护一个 WeakMap 记录已克隆过的源对象及其对应的新对象:
- 每次进入递归前,先查 WeakMap 是否已有该源对象的克隆结果,有则直接返回
- 克隆新对象后,立即将
源 → 新对象映射存入 WeakMap - WeakMap 适合此场景:键是对象,自动垃圾回收,不影响内存管理
简易可运行示例(支持数组、对象、null、Date)
以下是一个轻量但健壮的递归深拷贝函数:
<font size="2">function deepClone(obj, seen = new WeakMap()) {<br> if (obj === null || typeof obj !== 'object') return obj;<br> if (seen.has(obj)) return seen.get(obj);<br><br> let clone;<br> if (Array.isArray(obj)) {<br> clone = [];<br> } else if (obj instanceof Date) {<br> clone = new Date(obj.getTime());<br> } else if (obj instanceof RegExp) {<br> clone = new RegExp(obj);<br> } else {<br> clone = {};<br> }<br><br> seen.set(obj, clone);<br> for (let key in obj) {<br> if (Object.prototype.hasOwnProperty.call(obj, key)) {<br> clone[key] = deepClone(obj[key], seen);<br> }<br> }<br> return clone;<br>}</font>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










