什么是JSONjavascript_如何解析和序列化数据【教程】

JSON不是JavaScript子集,而是独立数据格式;JS中仅JSON.parse()和JSON.stringify()原生支持JSON处理,其他操作均依赖二者。

JSON 不是 JavaScript 的子集,而是一种独立的数据格式;JSON.parse()JSON.stringify() 是 JS 中唯二原生支持 JSON 处理的函数,其他所谓“解析”都绕不开它们。

为什么 JSON.parse() 会报错:Unexpected token

这是最常见的错误,本质是传入了非合法 JSON 字符串。注意:JS 对象字面量(如 {name: "Alice"})不是 JSON;JSON 要求键名和字符串值必须用双引号包裹,且不支持尾逗号、注释、undefined、function、Symbol、Date 对象等。

  • ❌ 错误示例:JSON.parse("{name: 'Alice'}") —— 单引号 + 无引号键名
  • ❌ 错误示例:JSON.parse('{"age": undefined}')

    —— undefined 在 JSON 中非法
  • ✅ 正确写法:JSON.parse('{"name": "Alice", "age": 28}')
  • ⚠️ 额外建议:后端返回前未 JSON.stringify()、前端误把 responseText 当作已解析对象、fetch 未调用 .json(),都会导致传给 JSON.parse() 的是 HTML 或空字符串

JSON.stringify() 为什么丢数据或报错

它只序列化对象自身可枚举、值为基本类型或 null 的属性;遇到函数、undefined、Symbol、循环引用会直接忽略或抛错。

  • JSON.stringify({a: undefined, b: () => {}})"{}"(静默丢失)
  • JSON.stringify({x: {y: 1}, z: {}}); const obj = {x: {y: 1}}; obj.z = obj;TypeError: Converting circular structure to JSON
  • ✅ 控制序列化行为可用第二个参数 replacer(数组或函数)过滤/转换值,第三个参数 space 控制缩进
  • ✅ 处理循环引用需手动剥离,或用库如 flatted,但多数场景应从数据建模阶段避免

浏览器里用 fetch().then(r => r.json()) 算不算“解析”

算,而且更安全。因为 Response.json() 内部调用的就是 JSON.parse(),但它自动校验响应头 Content-Type: application/json,并在解析失败时 reject Promise,比手动 JSON.parse() 更健壮。

  • ✅ 推荐写法:fetch("/api/user").then(r => r.json()).then(data => console.log(data))
  • ⚠️ 注意:r.json() 只能调用一次,重复调用会 reject;若需多次使用,应先存为变量
  • ⚠️ 常见误区:以为 fetch() 自动解析,其实它只返回 Response 对象,不解析任何内容

真正容易被忽略的是:JSON 规范本身不允许 NaN、Infinity、-Infinity,但 V8(Chrome / Node.js)在 JSON.stringify() 中会把它们转成 null,而其他引擎行为可能不同;如果数据中存在这类值,不要依赖默认序列化结果。