JavaScript解析和序列化JSON依赖JSON.parse()和JSON.stringify():前者将字符串转对象但容错极低,后者将对象转字符串会静默过滤非法值,二者均需谨慎处理类型兼容性与错误边界。

JavaScript 中解析和序列化 JSON 数据,核心就靠两个原生方法:JSON.parse() 和 JSON.stringify()。它们不依赖第三方库,但对格式和类型极其严格——不是“能跑就行”,而是“错一点就崩”。用对了很轻巧,用错了常卡在 SyntaxError 或静默丢数据上。
JSON.parse():字符串 → 对象,容错性极低
它只接受符合 JSON 标准的字符串,任何偏差都会直接抛 SyntaxError:
- 键名和字符串值必须用双引号,
{"name": 'Alice'}❌(单引号)、{name: "Alice"}❌(键没引号) - 不能有尾部逗号:
{"a": 1, "b": 2,}❌ - 不能含
undefined、function、Symbol、注释或 JavaScript 特有语法 - 后端返回的响应体是
Response对象,不是字符串,不能直接传给JSON.parse()
安全做法:始终用 try...catch 包裹,尤其处理 API 响应时:
try {
const res = await fetch('/api/user');
const data = await res.json(); // 推荐:用 res.json(),它内部已做 parse
} catch (e) {
console.error('解析失败:', e.message);
}
JSON.stringify():对象 → 字符串,会静默过滤
它不是“原样转字符串”,而是一套有规则的序列化过程,很多值会被悄悄跳过或转换:
立即学习“Java免费学习笔记(深入)”;
-
undefined、function、Symbol类型的属性值,连同整个键值对一起消失 -
Date对象自动转成 ISO 字符串(如"2024-01-01T00:00:00.000Z"),不再是Date实例 -
RegExp变成空对象{},NaN和Infinity变成null - 遇到循环引用(比如对象 A 的属性指向对象 B,B 又指向 A),直接抛
TypeError
想控制输出内容?可用第二个参数 replacer:
// 只保留 name 和 age 字段 JSON.stringify(user, ['name', 'age']); // 过滤掉敏感字段或转换日期 JSON.stringify(obj, (key, value) => key === 'password' ? undefined : value instanceof Date ? value.toISOString() : value );
常见场景下的实用处理方式
原生 JSON 不支持 Date、BigInt、Map、Set 等类型,需手动干预:
-
Date:序列化前调
.toISOString(),解析后用new Date(str)恢复 -
BigInt:
JSON.stringify(123n)会报错,可借助replacer转为带标识的字符串,如{"_type": "bigint", "value": "123"} -
Map / Set:先转成数组或普通对象,例如
JSON.stringify(Array.from(myMap)) -
深拷贝:
JSON.parse(JSON.stringify(obj))可用于纯数据对象,但会丢失函数、日期实例、正则等 —— 仅适合配置项、表单数据这类简单结构
前后端联调时最容易踩的坑
很多“解析失败”不是代码问题,而是约定没对齐:
- 后端返回了
404或500状态,但响应体仍是 JSON(比如错误详情),res.json()仍会成功执行,需配合res.ok判断 - 前端传参用了单引号或尾逗号,后端日志里看着像 JSON,其实不是合法 JSON 字符串
- 后端返回了
null、undefined或时间戳数字,前端误以为是 Date 实例,调用.getFullYear()报错
建议封装统一的 safeParse 和 safeStringify 工具函数,把日期、BigInt、Map 等业务常用类型的处理逻辑收口管理。


















