json.parse() 和 json.stringify() 需加防护:parse 必须 try/catch 避免 syntaxerror,stringify 会静默丢弃函数/undefined/symbol 等,应善用 reviver/replacer 控制转换,且二者不适用于 map、set、date 等非标类型。

直接用 JSON.parse() 和 JSON.stringify() 很方便,但不加防护容易崩溃或丢数据。关键不是“能不能用”,而是“怎么避免静默失败和意外转换”。
JSON.parse() 必须加 try/catch
它对输入极其敏感,单引号、尾逗号、undefined 字面量、注释、NaN 都会立刻抛 SyntaxError,导致脚本中断。
- ❌ 错误写法:
JSON.parse("{'name':'Alice'}")(单引号) - ❌ 错误写法:
JSON.parse('{"age":25,}')(尾逗号) - ❌ 错误写法:
JSON.parse('{"x":undefined}')(undefined 不是 JSON 类型) - ✅ 安全写法:始终包裹 try/catch,尤其处理 API 响应或用户输入时
try {<br> const data = JSON.parse(input);<br>} catch (e) {<br> console.warn('JSON 解析失败,使用默认值', e.message);<br> data = { error: true };<br>}
JSON.stringify() 会悄悄丢东西
它不是“把对象原样转成字符串”,而是按规则过滤:函数、undefined、Symbol 键值会被跳过;数组里对应位置变成 null;Date 自动转 ISO 字符串;循环引用直接报错。
- 对象中:
{ a: 1, b: undefined, c: () => {} }→{"a":1} - 数组中:
[1, undefined, /test/]→[1,null,null] - Date:
{ t: new Date() }→{"t":"2026-08-28T06:19:00.000Z"}(不再是 Date 实例) - 若需保留特殊类型,用
replacer函数手动控制
JSON.stringify(obj, (key, value) =><br> value instanceof Date ? value.getTime() : value<br>);
用 reviver 和 replacer 做可控转换
这两个参数是处理非标数据的核心工具,不用它们就只能接受默认行为。
-
JSON.parse(str, reviver):在解析每层键值时执行,适合恢复 Date、转换数字字符串为 number 等 -
JSON.stringify(obj, replacer, space):replacer 可以是数组(白名单属性)或函数(逐个改写) - 例如只保留 id、name、createdAt:
JSON.stringify(data, ['id', 'name', 'createdAt'], 2)
JSON.parse(jsonStr, (k, v) =><br> k === 'createdAt' || k === 'updatedAt' ? new Date(v) : v<br>);
别把它们当深拷贝或万能序列化器
它们解决的是 JSON ↔ JS 值的互转,不是通用对象操作工具。
- 不能处理 Map、Set、RegExp、Promise、BigInt、TypedArray —— 这些需手动映射或用
structuredClone(现代环境) - 不等于深拷贝:
JSON.parse(JSON.stringify(obj))会丢失原型、方法、undefined、循环引用,且 Date 变字符串 - localStorage 场景下必须 stringify + parse,但要注意数据结构是否支持
- API 请求中,
fetch(...).then(r => r.json())已内置 parse,无需再调用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











