强制 JSON.stringify() 发出这样做的 NaN / Infinity 或 JS JSON 库
Posted
技术标签:
【中文标题】强制 JSON.stringify() 发出这样做的 NaN / Infinity 或 JS JSON 库【英文标题】:Force JSON.stringify() to emit NaN / Infinity or JS JSON lib that does so 【发布时间】:2014-03-20 17:54:07 【问题描述】:我正在研究将 NaN/Infinity 支持添加到使用 JSONRPC 进行客户端/服务器交互的现有科学应用程序的可行性。许多 JSON 库确实(在某些情况下可选)处理 NaN 和 Inf,例如:
Python json 读写 Java Jackson 读取但写入字符串而不是裸字 Java GSON 读写 javascript 可以read我知道 JSON spec 不支持 NaN 和 Infinity,并且知道 related questions。但是,AFAICT 是否有某种方式可以强制原生 JS JSON.stringify()
方法发出 NaN/Infinity,或者是否有一个 JS JSON 库可以做到这一点,这个问题没有得到解答。与引用的问题可能存在细微差别,但很重要。到目前为止,我一直无法发现这样的方法或库,所以我在这里。编写自己的 JSON 序列化程序是唯一的选择吗?
请注意,JSON.stringify()
的 replacement
参数没有帮助,至少在我手中是这样。
更新: 将 NaN/Infinity 等作为字符串发出会使这些字符串的语义不明确。它们需要像在 Python 和 GSON 实现中一样作为裸词发出。
【问题讨论】:
这正是replacement
参数作业,没那么难。也许您可以详细说明您的实际问题,以及示例和示例数据?
JSON.stringify(a:1,b:1/"gg", c:d:5, function(a,b,c)if(Object.is(NaN , b))return "NaN"; return b;)
@dandavis 查看上面的更新。
如果你要否决这个问题,至少解释一下它有什么问题,以便我解决它。
如果您担心字符串冲突并希望使用快速的本机解析器,您可以使用 guid 代替,例如:"NaN"。
【参考方案1】:
这是一个例子
Javascript
var array1 = [-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity],
json = JSON.stringify(array1, function (key, value)
if (value !== value)
return 'NaN';
if (value === Infinity)
return 'Infinity';
if (value === -Infinity)
return '-Infinity';
return value;
),
array2 = JSON.parse(json, function (key, value)
if (value === 'NaN')
return NaN;
if (value === 'Infinity')
return Infinity;
if (value === '-Infinity')
return -Infinity;
return value;
);
console.log(json);
console.log(array2);
输出
["-Infinity",-1,0,1,2,"NaN",4,5,"Infinity"]
[-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity]
参考文献
JSON.stringify
JSON.parse
开启jsFiddle
更新:
Javascript
var array1 = [-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity],
json = JSON.stringify(array1, function (key, value)
if (value !== value)
return '0/0';
if (value === 1/0)
return '1/0';
if (value === -1/0)
return '-1/0';
return value;
),
array2 = JSON.parse(json, function (key, value)
if (value === '0/0')
return 0/0;
if (value === '1/0')
return Infinity;
if (value === '-1/0')
return -1/0;
return value;
);
console.log(json);
console.log(array2);
输出
["-1/0",-1,0,1,2,"0/0",4,5,"1/0"]
[-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity]
开启jsFiddle
【讨论】:
见上面的更新 - 你使用的字符串的语义现在是模棱两可的。 他们好吗ambiguous?您没有向我们提供任何示例数据。我使用的示例仅是数字。因此,在这种情况下,这些字符串表示并不模棱两可,它们只表示那些特定的值。 如果你想要一个不符合规范的库,我建议你获取一份'JSON2' 并修改代码以满足你的需要。 或者,如果您担心的是字符串表示并想要替代方法,请尝试If you evaluate 1/0 you get Infinity, if you evaluate -1/0 you get -Infinity, if you evaluate 0/0 you get NaN.
因为,例如,字符串 Infinity 现在有两种可能的含义——字符串 Infinity 和无穷大的数字表示,接收者无法知道选择哪个含义。我无法提供代表所有可能发生的情况的示例数据 - 它几乎可以是任何对象。【参考方案2】:
JSON.stringify
的replacement
参数是非常适合这项工作的工具。
JSON.stringify(data, function(key, value)
if (value === Infinity)
return "Infinity";
else if (value === -Infinity)
return "-Infinity";
else if (value !== value)
return "NaN";
return value;
);
另一方面,您可以使用JSON.parse
的reviver
参数。
JSON.parse(data, function(key, value)
if (value === "Infinity")
return Infinity;
else if (value === "-Infinity")
return -Infinity;
else if (value === "NaN")
return NaN;
return value;
);
【讨论】:
else
s 之后不需要return
s
查看上面的更新 - 此处的解决方案将歧义引入您选择表示 NaN 和 Inf 的字符串的语义中。
@Xotic750 我更喜欢else if
,因为它可以缩短代码并且在这种情况下不会影响功能。不过感谢您的关注。
@elhefe 我同意,它们现在是模棱两可的,使用现有的本机实现我们无能为力。我明白了,你找到了解决方案,破解 JSON2 库。总帐以上是关于强制 JSON.stringify() 发出这样做的 NaN / Infinity 或 JS JSON 库的主要内容,如果未能解决你的问题,请参考以下文章
JSON.stringify 将 Infinity 转换为 null
JSON.stringify 将 Infinity 转换为 null