JSON.parse(JSON.stringify(obj))无法保留函数、RegExp等类型,因JSON标准不支持;应改用structuredClone()(现代环境首选)或手写递归克隆(WeakMap防循环+显式重建),Lodash需customizer定制,JSON路径打补丁无效。

JSON.parse(JSON.stringify(obj)) 本身无法保留函数、RegExp、undefined、Date、Symbol 等类型——这不是代码写得不对,而是 JSON 标准根本不支持它们。想“避免丢失”,不能在 JSON 路径上修修补补,而要换掉整个方案。
优先用 structuredClone()(现代环境首选)
Chrome 98+、Firefox 94+、Safari 15.4+、Node.js 18.13+/20.6+ 已原生支持,无需依赖:
- ✅ 正确复制 RegExp(含 source 和 flags)
- ✅ 保留 undefined 字段(不会跳过)
- ⚠️ Function 默认克隆为引用(函数体不变,但 this 和闭包需自行验证)
- ❌ 不支持 Symbol、Promise、DOM 节点、WeakMap/WeakSet
- ✅ 天然防循环引用,无额外配置
需要兼容旧环境或深度定制时,手写递归克隆
核心是分类判断 + WeakMap 防循环 + 显式重建特殊值:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 遇到 Function:直接赋值(保持引用),或用
value.bind({})创建无上下文副本 - 遇到 RegExp:用
new RegExp(value.source, value.flags)新建实例 - 遇到 undefined:不跳过,显式赋值
cloned[key] = obj[key] - 遍历用
Reflect.ownKeys(obj),覆盖不可枚举属性和 Symbol 键 - 用 WeakMap 缓存源对象 → 克隆对象映射,重复出现时直接返回已有结果
已有工程化基础?用 Lodash 并启用 customizer
_.cloneDeep() 默认丢弃函数和 RegExp,但可通过 customizer 回调接管:
立即学习“Java免费学习笔记(深入)”;
- 对 function 类型,显式返回
value(保留原函数) - 对 undefined,可提前转为
null再交由 cloneDeep 处理,避免字段消失 - 检测
value instanceof RegExp,返回new RegExp(value.source, value.flags) - 注意:Symbol 和原型链仍需额外处理,customizer 不自动覆盖
不推荐在 JSON 上打补丁
虽然可用 replacer/reviver 拦截 Date 或简单标记 RegExp,但:
- 无法真正恢复函数(序列化后已无函数体信息)
- undefined 在 stringify 阶段就被忽略,reviver 无从还原
- Symbol 键根本不会进入 replacer 流程
- 一旦有循环引用,仍会直接报错

















