json.parse()仅支持标准类型,date、map、set、regexp等会丢失原始特征;需用reviver函数或预转换策略还原,并必须用try...catch处理解析异常。

JavaScript 中把 JSON 字符串解析为复杂对象,核心靠 JSON.parse(),但它本身只处理标准 JSON 数据——即字符串、数字、布尔值、null、普通对象和数组。而真实业务中的“复杂对象”,比如含 Date、Map、Set、正则、函数、循环引用或自定义类实例的数据,原生 JSON.parse() 无法直接还原,需要额外干预。
哪些数据类型在网络传输中会“丢失”原始特征
JSON 是纯数据格式,不保留 JavaScript 运行时类型信息。以下常见类型经 JSON.stringify() → 网络传输 → JSON.parse() 后会发生变化:
-
Date 对象:序列化后变成 ISO 字符串(如
"2025-08-19T14:30:00.000Z"),解析后是普通字符串,不再是Date实例 -
Map / Set:原生不支持,
JSON.stringify()会返回空对象{}或空数组[],解析后无法恢复结构 - RegExp:被忽略或转为空对象,正则逻辑完全丢失
-
undefined / Function / Symbol / BigInt:在
stringify阶段就被过滤或报错,根本传不过去 -
循环引用对象:
JSON.stringify()直接抛错,无法完成序列化
用 reviver 函数还原关键类型(如 Date)
JSON.parse(text, reviver) 的第二个参数 reviver 是一个回调函数,在每个键值对被解析后立即执行,可用于识别并重建特殊类型:
例如,自动把所有形如 "2025-08-19T..." 的字符串转回 Date:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
function dateReviver(key, value) {
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
const d = new Date(value);
return isNaN(d.getTime()) ? value : d;
}
return value;
}
const jsonStr = '{"created":"2025-08-19T10:00:00Z","name":"order"}';
const obj = JSON.parse(jsonStr, dateReviver);
// obj.created 是 Date 实例,不是字符串
处理 Map、Set 等非标准结构的常用策略
原生 JSON 不支持这些类型,需约定传输协议,常见做法有:
-
序列化前手动转换:发送前把
Map转成二维数组[["k1","v1"],["k2","v2"]],接收后用new Map(parsedArray)恢复 -
加类型标记字段:在 JSON 中嵌入
"$type": "Map"和"$data"字段,解析时用reviver识别并构造 - 使用成熟序列化库:如 serialize-javascript(侧重安全反序列化)或自研轻量方案,避免重复造轮子
必须搭配 try...catch 做健壮解析
网络传输中 JSON 字符串可能因截断、编码错误、服务端 bug 导致格式非法,JSON.parse() 会直接抛异常,中断执行:
try {
const data = JSON.parse(jsonString);
// 成功解析,继续处理
} catch (err) {
console.error('JSON 解析失败:', err.message);
// 可降级为默认值、空对象,或提示用户重试
}
尤其在 fetch 或 XMLHttpRequest 的 response.text() 后调用时,这步不能省略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










