【问题标题】:Serialization of NaN and Infinity in JSON. Why not supported?JSON 中 NaN 和 Infinity 的序列化。为什么不支持?
【发布时间】:2019-07-20 17:58:27
【问题描述】:

通过 JavaScript 实现 JSON 中 NaN 和 Infinity 序列化的常识很简单:

JSON.stringify({ x: NaN });
"{"x":null}"

JSON.stringify({ x: Infinity });
"{"x":null}"

问题是这个奇怪决定的背后是什么?

【问题讨论】:

标签: javascript json serialization


【解决方案1】:

每RFC 7159 - The JavaScript Object Notation (JSON) Data Interchange Format

不允许在下面的语法中表示的数值(例如 Infinity 和 NaN)。

我推测这是因为 NaN 和 Infinity 实际上并不表示数字和/或不能用任何类型的数字格式表示。

【讨论】:

  • 我想只允许数字表示使规范更简单
【解决方案2】:

我不能告诉你这个决定背后的原因,但这里有一种可能的处理方法:

const obj = {foo: NaN, bar: Infinity, baz: 42}
JSON.stringify(obj, (name, val) => typeof(val) === 'number' && (isNaN(val) || !isFinite(val)) ? val.toString() : val)

输出是:

{"foo":"NaN","bar":"Infinity","baz":42}

【讨论】:

  • 看起来他们开始尝试提出一个标准,该标准不假定任何特定的实现在任何一端,因此留下了不被普遍支持的东西,例如 NaN 或 Inf。然后在下一段中,它承认 IEEE 754(实际上)几乎无处不在……恕我直言,最好包含诸如 NaN、Inf 之类的东西,然后将其留给那些极少数不这样做的实现。如果遇到的话,不要让他们弄清楚如何处理。 ASN.1,通常也以文本格式编码浮点数,确实有 NaN,+/-Inf
  • 有趣的是,如今 ASN.1 可以使用 JSON 作为有线格式。关于 ASN.1 应该如何处理 NaN 的标准似乎有点模糊,如果编码为 JSON,则为 +/-Inf。抱歉,这有点像兔子洞,但我觉得比较设计决策很有趣。
  • 还有这个:github.com/json5/json5,它解决了 JSON 的一些恼人的限制。我注意到一些 JSON 解析器已经在这里提供了一些额外的宽大处理,比如允许 JSON 中的内联 cmets。我提出的一个额外建议是允许在数字末尾添加一个尾随“n”以支持BigInt。
  • 这看起来相当不错和明智。如果 IETF 能接受,那就太好了。
猜你喜欢
  • 2015-12-24
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 2014-01-23
  • 2011-11-17
  • 2021-01-26
相关资源
最近更新 更多