structuredclone是处理复杂嵌套数组的首选方案,一行代码即可深拷贝并保留date、map、set等类型及循环引用,不支持函数、symbol等非可序列化值。

处理复杂的嵌套数组,关键在于确保每一层的引用类型(对象、数组、Date、Map、Set 等)都被真正复制,而不是共享内存地址。简单方法如 [...arr] 或 arr.slice() 只能拷贝第一层,遇到嵌套数组或对象就失效。
优先用现代原生方案:structuredClone
这是目前最推荐的方式,浏览器兼容性已较好(Chrome 98+、Firefox 94+、Safari 15.4+),支持嵌套数组、对象、Date、RegExp、Map、Set,甚至能正确处理循环引用:
-
一行代码搞定:
const deepCopy = structuredClone(originalArray); -
不丢失类型信息:比如
new Date()拷贝后仍是 Date 实例,不是字符串 - 自动防循环引用:内部用结构化克隆算法,不会栈溢出
- 局限:不支持函数、Symbol、undefined、Promise、Error 实例等非可序列化值
兼容旧环境时用 lodash 的 cloneDeep
如果项目需支持 IE 或老版浏览器,lodash.cloneDeep 是最稳妥的选择:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 覆盖全面:能处理函数(作为不可执行的空对象)、Symbol、循环引用、自定义类实例(部分场景)
-
开箱即用:
import { cloneDeep } from 'lodash-es'; const copy = cloneDeep(nestedArr); - 注意体积:Tree-shaking 后仍约 10–15KB,若仅需深拷贝,可考虑轻量替代方案
手动递归实现(适合学习或极简依赖场景)
若不想引入外部库,又需要比 JSON 方法更强的控制力,可手写基础递归版本:
-
识别类型:用
Object.prototype.toString.call()判断 Array、Object、Date、Map、Set 等 - 记录已拷贝对象:用 WeakMap 缓存源对象 → 目标对象映射,避免循环引用死循环
-
逐类型处理:
- Array → 创建新数组,递归拷贝每个元素
- Date/RegExp → 直接 new 构造新实例
- Map/Set → 遍历键值对,分别拷贝键与值
- 普通对象 → 递归遍历自有属性
- 跳过函数和 Symbol:它们通常不参与数据逻辑,保留 undefined 或忽略更安全
慎用 JSON.parse(JSON.stringify())
它对纯数据嵌套数组“看似有效”,但隐患明显:
- 数据丢失:Date 变成字符串、RegExp 变成空对象、undefined 和 Symbol 被过滤、函数直接消失
- 原型链断裂:拷贝后是 plain object,不再是原构造器实例
-
循环引用报错:
TypeError: Converting circular structure to JSON - 仅适用于简单场景:比如配置项数组、纯数字/字符串嵌套结构
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










