json.stringify将nan、infinity和-infinity统一序列化为null,因json标准不支持这些ieee 754扩展值;为保障可解析性与兼容性,ecmascript规范强制映射为合法json值null,该过程不可逆,原始信息丢失。

JSON.stringify 对 NaN、Infinity 和 -Infinity 的处理不是“转换错误”,而是明确写入规范的行为:它们统一被序列化为 null。
为什么是 null,而不是字符串或报错?
JSON 标准本身不支持 NaN 或 Infinity 字面量。原生 JSON 语法只允许 null、布尔值、数字(有限十进制)、字符串和对象/数组。JavaScript 中的 NaN 和 Infinity 属于 IEEE 754 浮点扩展值,不属于 JSON 合法数值范围。为保持兼容性和可解析性,ECMAScript 规范强制规定:这些值在序列化时必须映射为 null,而非抛出错误或保留原始语义。
实际表现与验证
以下行为一致且可复现:
-
JSON.stringify({ a: NaN })→'{"a":null}' -
JSON.stringify({ b: Infinity })→'{"b":null}' -
JSON.stringify({ c: -Infinity })→'{"c":null}' - 即使嵌套在数组中:
JSON.stringify([NaN, Infinity])→'[null,null]'
注意:null 不代表“丢失”,而是有明确语义的替代
这个 null 是 JSON 字符串里的合法值,不是 undefined 或空字段。后续用 JSON.parse() 解析后,得到的是真正的 JavaScript null,不再是原来的 NaN 或 Infinity。也就是说,该过程是不可逆的类型降级,原始信息已丢失。
如何避免这种隐式替换?
若需保留语义,必须主动干预:
- 使用
replacer函数提前识别并转为自定义字符串(如"NaN"、"Infinity") - 解析端约定将特定字符串再还原为对应值(例如
value === "Infinity" ? Infinity : value) - 对关键字段做预处理,例如把
Infinity替换为一个业务上无歧义的大数(如Number.MAX_SAFE_INTEGER)











