JavaScript JSON如何操作_如何进行序列化和解析【教程】

JSON.stringify() 遇循环引用报 TypeError,undefined/function/Symbol 值被静默丢弃;JSON.parse() 遇非法 JSON 立抛 SyntaxError;需 try...catch 处理;安全序列化需 replacer 或专用库;parse 结果无原型/类型信息,需 reviver 手动还原。

JSON.stringify() 什么时候会失败

它本身几乎不会抛错,但传入循环引用对象时会直接报 TypeError: Converting circular structure to JSON。比如:

const obj = { a: 1 };
obj.self = obj;
JSON.stringify(obj); // 报错
还有像 undefinedfunctionSymbol 这类值在序列化时会被静默丢弃(不是报错),容易导致数据丢失却没提示。

  • 对象里有 undefined 属性 → 序列化后该属性消失
  • 值是 function() → 对应字段被跳过
  • 用了 Symbol('key') 作属性名 → 完全不进入输出字符串

JSON.parse() 遇到非法 JSON 怎么办

只要字符串不符合 JSON 语法,就会立刻抛 SyntaxError,比如单引号、末尾逗号、注释、未转义的控制字符。常见错误输入:

JSON.parse("{'name': 'Alice'}"); // 单引号 → 报错
JSON.parse('{"age": 25,}'); // 末尾逗号 → 报错
JSON.parse('{"msg": "hello\nworld"}'); // 换行没转义 → 报错
别指望它自动修复或宽容处理。如果来源不可控(如用户粘贴、旧系统输出),必须用 try...catch 包裹:
try {
  const data = JSON.parse(input);
} catch (e) {
  console.error('解析失败:', e.message);
  // 处理 fallback 或提示用户
}

如何安全地序列化带函数或循环引用的对象

原生 JSON.stringify() 不支持,得自己干预。常用两个方向:

  • replacer 参数过滤掉非法值:传入函数,对每个键值对做判断,返回要保留的值,或 undefined 跳过
  • JSON.stringify(obj, customReplacer) + 手动展开循环引用(例如记录已访问对象,遇到重复就替换成 "[Circular]"
  • 更省事:用现成库如 flattedcycle,它们提供 stringify()parse() 的增强版,能处理循环引用
注意:自定义 replacer 不能修复 undefined 作为对象属性值的问题——它只影响值,不恢复被删掉的键。

JSON 和 JavaScript 对象的边界在哪

很多人误以为 JSON.parse() 返回的就是“原始对象”,其实它只保证是普通 ObjectArray,不保留原型、方法、日期实例、正则等。例如:

JSON.parse('{"time": "2025-01-01T00:00:00Z"}').time instanceof Date; // false
JSON.parse('{"pattern": "/\\d+/"}').pattern instanceof RegExp; // false
如果你需要还原特定类型,得在 reviver 函数里手动转换:
JSON.parse(jsonStr, (key, value) => {
  if (key === 'time' && typeof value === 'string') {
    r

eturn new Date(value); } return value; });
这个细节常被忽略,结果拿到字符串还以为是 Date 对象,调 .toISOString() 就崩了。