JSON.parse(JSON.stringify())无法深拷贝Date和RegExp,应识别类型后用构造器重建:Date用getTime()再new Date(),RegExp用source和flags新建;需处理不可枚举属性、原型链及循环引用,推荐优先使用structuredClone()。

深拷贝 Date 和 RegExp 对象,不能靠 JSON.parse(JSON.stringify()) —— 它会让 Date 变成字符串、RegExp 变成空对象,类型和状态全丢。核心思路是:识别类型,用对应构造器新建实例,并复制关键状态。
识别并用构造器重建
Date 和 RegExp 都是不可变的内置对象,但它们的状态需要显式提取再重建:
-
Date:取
getTime()或toString(),再传给new Date()。推荐new Date(original.getTime()),避免时区解析歧义 -
RegExp:取
source(正则模式)和flags(如'gim'),调用new RegExp(original.source, original.flags)。直接new RegExp(original)在部分环境也支持,但显式拆解更可靠
注意不可枚举属性和原型链
虽然 Date 和 RegExp 默认不带自定义属性,但如果手动添加过(比如用 Object.defineProperty 设置了不可枚举字段),或继承自自定义子类,就得保留原型和完整属性描述:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
Object.getPrototypeOf(original)获取原型,再用Object.create()创建新实例 - 用
Object.getOwnPropertyDescriptors()拿到所有属性(含 getter/setter、不可枚举项),逐个深拷贝值后定义到新对象上
配合循环引用防护统一处理
即使 Date/RegExp 本身不可变,整个深拷贝流程仍需支持循环引用。建议用 WeakMap 缓存已处理对象:
立即学习“Java免费学习笔记(深入)”;
- 每次进入拷贝前,先查
WeakMap是否已有该源对象的副本,有则直接返回 - 对 Date/RegExp 虽非必须,但统一逻辑可避免后续扩展 Map/Set 时漏掉缓存
- 缓存应在新建实例后、填充状态前完成映射,防止递归卡死
现代方案优先用 structuredClone()
Chrome 98+、Firefox 94+、Node.js 17.0+ 已支持原生 structuredClone(),它原生支持 Date、RegExp、Map、Set、TypedArray 等,且自动处理循环引用:
- 简单场景直接用:
const cloned = structuredClone(original); - 不支持的环境再回退到手写逻辑;注意它不复制函数、undefined、Symbol 和原型方法

















