深拷贝与序列化目标不同:深拷贝生成独立内存对象,如structuredclone支持循环引用和现代类型;序列化生成字符串用于跨环境传输,如json会丢失函数、undefined等信息且不支持map/set。

引用类型的深拷贝和序列化是两个目标不同、机制不同的操作,不能混为一谈。深拷贝解决的是“内存中对象是否独立”,序列化解决的是“数据能否跨环境传输或持久化”。关键区别在于:深拷贝产出的是一个可直接使用的 JavaScript 对象实例;序列化产出的是一段字符串(或其他格式字节流),必须反序列化后才能还原为对象,且这个过程天然有信息损失。
深拷贝引用类型的核心要求
对包含对象、数组、Map、Set、Date、RegExp 等引用类型的值做深拷贝,必须满足:
- 所有嵌套层级的引用类型都生成新实例,彼此不共享内存地址
- 支持现代内置类型(如 Map、Set、TypedArray、BigInt、Symbol)
- 能正确处理循环引用,不报错也不陷入死循环
- 不丢失函数、undefined、正则表达式等运行时有效值(除非明确不需要)
structuredClone 是当前最优解
现代浏览器与 Node.js 17.0+ 原生支持 structuredClone(),它是专为深拷贝设计的 API:
- 自动识别并克隆 Date、RegExp、Map、Set、Blob、File、ImageData 等类型
- 原生支持循环引用检测与安全克隆
- 不丢 function、undefined、Symbol,保留原始语义
- 比 JSON 方案快且健壮,无字符串编解码开销
用法简单:const copy = structuredClone(original);
序列化不是深拷贝工具,只是数据交换手段
JSON.stringify / parse 经常被误当作深拷贝方案,但它本质是序列化流程:
- Date 变成 ISO 字符串,RegExp 变成空对象,function 和 undefined 直接消失
- NaN → null,Infinity → null,Symbol 和 BigInt 被忽略
- 遇到循环引用立即抛错,无法处理 Map/Set 内部结构
- 结果是字符串再转回对象,中间经历两次遍历,性能差、不可靠
它只适合纯数据对象(POJO)的临时转换,比如存 localStorage 或发 fetch 请求体。
什么时候该选序列化而不是深拷贝?
当你需要以下任一能力时,才该走序列化路线:
- 把状态写入 localStorage 或 IndexedDB(只能存字符串/ArrayBuffer)
- 通过 HTTP 发送请求体,或接收服务端返回的 JSON 数据
- 在 SSR 中将初始数据注入 HTML 的 script 标签供客户端接管
- 跨 Worker 或 iframe 传递数据(需配合 postMessage)
注意:这些场景下你并不需要“内存隔离”,而是需要“格式标准化”和“边界穿越能力”。











