JSON.parse()和JSON.stringify()处理复杂嵌套数据存在多重运行时风险:不支持函数、undefined、Symbol、Date、RegExp、Map、Set及循环引用;大数精度丢失、NaN/Infinity转null、BigInt报错;不可信输入可能导致内存溢出或栈溢出。

直接用 JSON.parse() 和 JSON.stringify() 处理复杂嵌套数据,看似简单,实则暗藏多个易被忽视的运行时风险。核心问题在于:JSON 标准本身不支持函数、undefined、Symbol、Date、RegExp、Map、Set、循环引用等 JavaScript 原生类型,而这些在真实业务数据中极为常见。
丢失关键数据类型
调用 JSON.stringify() 时,无法序列化的值会被静默忽略或转换为 null/空字符串:
-
undefined字段直接被剔除(不是转成null) -
function和Symbol字段完全消失 -
Date对象变成 ISO 字符串,再用JSON.parse()后只是普通字符串,不再是 Date 实例 -
RegExp变成空对象{},Map/Set变成空对象或空数组
循环引用导致崩溃
若对象存在自引用或相互引用(如树结构父子双向指针、图结构节点关系),JSON.stringify() 会立即抛出 TypeError: Converting circular structure to JSON。这不是可捕获的逻辑错误,而是底层引擎中断,无法通过 try-catch“优雅降级”——除非提前检测或使用替代方案。
精度与边界值陷阱
JSON 只支持 IEEE 754 双精度浮点数:
立即学习“Java免费学习笔记(深入)”;
- 超过
Number.MAX_SAFE_INTEGER(2⁵³−1)的整数可能丢失精度,例如9007199254740993被序列化后可能变成9007199254740992 -
NaN、Infinity、-Infinity全部转为null,且无任何提示 -
BigInt直接报错:TypeError: Do not know how to serialize a BigInt
安全反序列化不可信输入
对用户输入或第三方 API 返回的 JSON 字符串执行 JSON.parse(),虽不执行代码(比 eval 安全),但仍需警惕:
- 超大字符串可能引发内存溢出或长时间阻塞主线程(尤其在低端设备)
- 深度嵌套对象可能触发 V8 的栈深度限制,抛出
RangeError: Maximum call stack size exceeded - 恶意构造的深层嵌套或超长数组可作为拒绝服务(DoS)攻击手段
不复杂但容易忽略。真正健壮的嵌套数据处理,往往需要定制序列化器、预检结构、设置解析深度/长度限制,或改用 MessagePack、Protocol Buffers 等二进制格式来规避 JSON 的固有局限。


















