深拷贝 Date 和 RegExp 需特殊处理:Date 直接 new Date(obj) 即可保留时间精度与 Invalid Date 状态;RegExp 需 new RegExp(obj.source, obj.flags) 后显式赋值 lastIndex;Map、Set 等需按类型构造并深拷贝内容;所有实现须用 WeakMap 处理循环引用。

深拷贝 Date 和 RegExp 不能靠 JSON.stringify 或简单递归,必须单独识别、构造新实例并还原关键状态。
Date 对象要保留时间精度和非法状态
直接 new Date(obj) 就行,它能正确复现毫秒级时间戳,也保留 Invalid Date 状态。不要用 toISOString() 或 valueOf() 转换,避免时区偏移或精度丢失。
-
new Date(dateObj)是最安全的克隆方式 - 不依赖
dateObj.getTime()手动传参(虽等效,但多一步且无必要) - 原始 Date 的
toString()、toUTCString()等行为完全一致
RegExp 对象需复制源码、标志和匹配位置
正则不只是模式,还包含 flags 和 lastIndex(尤其在全局匹配时)。只复制 source 和 flags 不够,lastIndex 必须显式赋值。
-
const copy = new RegExp(obj.source, obj.flags)创建基础实例 - 紧接着
copy.lastIndex = obj.lastIndex恢复上次匹配状态 - 这样克隆后的正则在
exec()或test()中行为与原对象一致
其他特殊对象也要按类型处理
Map、Set、ArrayBuffer、TypedArray、Error 等都有对应构造逻辑,不能统一用 {} 或 []。
- Map:遍历键值对,对 key 和 value 分别深拷贝后
set() - Set:逐项深拷贝后
add() - 函数、Symbol、undefined、null 等原始或不可序列化值,需原样保留或按需策略处理
循环引用必须提前缓存
所有深拷贝实现都要用 WeakMap 记录已处理对象,遇到重复引用直接返回缓存副本,否则递归会爆栈。
-
if (cache.has(obj)) return cache.get(obj)放在函数开头 -
cache.set(obj, copy)在创建空副本后立即执行
不复杂但容易忽略


















