任何想法,为什么JSON冷落楠+/-无限? 它把JavaScript中的奇怪情况的对象,否则将序列化的,都没有,如果它们包含NaN或+/-无穷大值。
看起来这已经一成不变的:见RFC4627和ECMA-262 (最后编辑部分24.3.2,JSON.stringify注4,507页):
有限的数字是通过调用字符串化仿佛
ToString(number)
。 楠无限不管符号表示为字符串null
。
任何想法,为什么JSON冷落楠+/-无限? 它把JavaScript中的奇怪情况的对象,否则将序列化的,都没有,如果它们包含NaN或+/-无穷大值。
看起来这已经一成不变的:见RFC4627和ECMA-262 (最后编辑部分24.3.2,JSON.stringify注4,507页):
有限的数字是通过调用字符串化仿佛
ToString(number)
。 楠无限不管符号表示为字符串null
。
Infinity
和NaN
不是关键字或任何特殊,他们是全球对象只是属性(如undefined
),因此是可以改变的。 这是因为这个原因JSON不包括他们在规范-在本质上,如果你做任何真正的JSON字符串应该具有的EcmaScript相同的结果eval(jsonString)
或JSON.parse(jsonString)
如果允许再有人可以注入代码类似于
NaN={valueOf:function(){ do evil }};
Infinity={valueOf:function(){ do evil }};
进入论坛(或其他),然后在该网站的任何使用JSON可能被破坏。
在原来的问题:我同意用户“cbare”中,这是JSON一个不幸的遗漏。 IEEE754定义了一个浮点数的这三个特殊值。 因此,JSON不能完全代表IEEE754浮点数。 事实上,这是更糟糕,因为JSON作为ECMA262 5.1定义甚至没有定义其编号是否基于IEEE754。 由于在ECMA262的字符串化()函数描述的设计流程确实提到了三个特殊IEEE值,可以怀疑这样做的目的实际上支持IEEE754浮点数字。
作为另外一个数据点,无关的问题:XML数据类型的xs:float和XS:他们是基于IEEE754浮点数字,它们支持这三个特殊值的表示,双做状态(见W3C XSD 1.0第2部分,数据类型)。
你能适应空对象模式,并在你的JSON表示这样的值
"myNum" : {
"isNaN" :false,
"isInfinity" :true
}
然后检查的时候,你可以检查的类型
if (typeof(myObj.myNum) == 'number') {/* do this */}
else if (myObj.myNum.isNaN) {/* do that*/}
else if (myObj.myNum.isInfinity) {/* Do another thing */}
我知道在Java中,你可以重写,以实现这样的事情序列化方法。 不知道您的序列化的,所以我不能就如何实现它的序列化方法的细节。
该字符串“无限”,“负无穷”和“南”强制所有在JS的预期值。 所以,我要说表示这些值是JSON作为字符串的正确方法。
> +"Infinity"
Infinity
> +"-Infinity"
-Infinity
> +"NaN"
NaN
它只是一个耻辱JSON.stringify默认情况下不这样做。 但是有一个办法:
> JSON.stringify({ x: Infinity }, function (k,v) { return v === Infinity ? "Infinity" : v; })
"{"x":"Infinity"}"
如果你有机会获得序列化代码,你可以代表无限为1.0E + 1024。 该指数是过大的双重代表和反序列化时,这是表示为无穷大。 工作WebKit的,不确定其他JSON解析器!
当前IEEE标准754-2008包括用于两个不同的64位浮点表示法定义:一个十进制的64位浮点类型和一个二进制的64位浮点型。
舍入后的字符串.99999990000000006
相同.9999999
在IEEE二进制64位表示,但它是不一样的.9999999
在IEEE十进制的64位表示。 在64位IEEE浮点小数.99999990000000006
回合值.9999999000000001
这是不一样的十进制.9999999
值。
由于JSON只是把数字值的小数位数的数字串是没有办法的,同时支持IEEE二进制和十进制浮点表示(如IBM的Power),以确定两个可能的IEEE数字浮点值的是一个系统意。
潜在的变通像{“关键”:无限}情况:
JSON.parse(theString.replace(/":(Infinity|-InNaN)/g, '":"{{$1}}"'), function(k, v) {
if (v === '{{Infinity}}') return Infinity;
else if (v === '{{-Infinity}}') return -Infinity;
else if (v === '{{NaN}}') return NaN;
return v;
});
总的想法是在解析时,我们会认识到,并与相应的JavaScript表示更换回的字符串替换无效值的出现次数。
如果你像我一样有过的序列化代码无法控制,你可以通过与空或任何其他值替代它们作为一个黑客位的如下处理NaN值:
$.get("file.json", theCallback)
.fail(function(data) {
theCallback(JSON.parse(data.responseText.replace(/NaN/g,'null')));
} );
从本质上说,当原始JSON解析器检测到无效的令牌.fail将被调用。 然后一个字符串替换来替换无效的标记。 在我的情况下,它是为串行器返回NaN值所以这种方法是最好的方法异常。 如果结果通常含有无效的标记,你会过得更好不要使用。获得$而是手工获取JSON结果,并始终运行字符串替换。