json标准不支持regexp和date直接序列化;需用replacer/reviver定制:date转iso字符串并标记$ date,regexp拆解source/flags存$ regex,再分别还原。

JSON 标准本身不支持 RegExp 和 Date 对象的直接序列化与解析。调用 JSON.stringify() 时,它们会被静默忽略(Date 变成字符串,RegExp 变成空对象 {});而 JSON.parse() 无法还原出原始类型。要正确处理这类“变异”,需在序列化和反序列化阶段主动介入。
使用 replacer 和 reviver 参数定制转换逻辑
JSON.stringify() 的第二个参数 replacer 可拦截值并替换;JSON.parse() 的第二个参数 reviver 可在解析后重构对象。这是最轻量、无需依赖库的方案。
- 对
Date:序列化时转为 ISO 字符串,并打上类型标记(如{"$date": "2024-05-20T10:30:00.000Z"});反序列化时识别该结构并新建Date实例 - 对
RegExp:序列化时提取source和flags,存为{"$regex": { "source": "...", "flags": "gim"}};反序列化时用new RegExp(source, flags)还原
注意 Date 的隐式转换陷阱
默认情况下,Date 对象在 JSON.stringify() 中会自动调用 toISOString(),但仅限顶层属性或未被 replacer 拦截的情况。若对象嵌套较深,或你希望保留时区信息(如 "2024-05-20T10:30:00+08:00"),需显式控制格式。避免依赖 toString() 或 toUTCString(),它们不符合 ISO 8601 且不可逆。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
RegExp 序列化的关键细节
RegExp.prototype.toString() 返回类似 "/abc/gi" 的字符串,看似简洁,但解析它需要正则表达式语法分析——容易出错且不安全(如含未转义斜杠或控制字符)。更可靠的做法是分别保存 source 和 flags 属性。特别注意:flags 是只读字符串(如 "gimsy"),不能通过 RegExp.prototype.flags 获取旧版浏览器兼容性,建议用 reg.exp.flags || (reg.global ? 'g' : '') + (reg.ignoreCase ? 'i' : '') + ... 兜底。
封装可复用的工具函数
将上述逻辑封装为两个函数,例如 safeStringify(obj) 和 safeParse(json),内部统一处理 Date、RegExp,还可扩展支持 Map、Set、BigInt 等。注意保持类型标识字段名唯一(如 $date、$regex),避免与业务数据冲突。若数据来自不可信来源,reviver 中应校验结构合法性,防止原型污染或构造恶意实例。










