我有这段代码:
function getSessionGUID() {
return (S4()+S4());
}
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
它清楚地返回一个字符串,但是如果你运行它很多次,你会注意到它有时会返回无穷大。
for (var i = 0; i < 100000; i++){ if(getSessionGUID() == Infinity) console.log("INFINITY"); }
871 x INFINITY
然后我注意到如果删除| 0,它就解决了问题:
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
结果:
for (var i = 0; i < 100000; i++){ if(getSessionGUID() == Infinity) console.log("INFINITY"); }
undefined
为什么会这样?在这两种情况下,值都会更改为字符串。
答案 0 :(得分:3)
您正在生成十六进制字符串。
当您使用==
运算符时,解释器会尝试将这两个值强制转换为相同的数据类型。将字符串与Infinity
进行比较时,该中间数据类型为Number
。当这些字符串包含字母“e”(一个有效的十六进制数字)并且它们被强制转换为Number
时,javascript将其解释为10 ^ x,最终为一些巨大的数字。
Number
s in javascript are 8 bytes,因此大于1.7976931348623157e308
的任何内容都被视为等于Infinity
。
解决此问题的最简单方法是将==
更改为===
,以便字符串不会被强制转换为数字。
if(getSessionGUID() === Infinity)
答案 1 :(得分:2)
JavaScript是动态类型的。没有整数浮点数。字符串数据类型。所有转换都是在内部完成的,具体取决于上下文。
+可以是字符串连接或添加,具体取决于上下文。
编辑:道歉。太晚了。但是,当与无穷大进行比较时,==执行转换为数字。在某些情况下,您生成了有效数字。
答案 2 :(得分:2)
我想我明白了。除了我的测试代码之外,所有这些都没有错。
如果你把这个字符串“11e51354”,你可以让它断言为true,因为Javascript会检查所有可以使它等于true的类型。
"11e51354" == Infinity # True
正确的测试将是:
"11e51354" === Infinity # False
它仍然是一个字符串,但不知何故,当我通过GET请求发送它时,它被转换为一个给Infinity的数字类型。
答案 3 :(得分:2)
这个测试揭示了答案:
for (var i = 0; i < 100000; i++){
var x=getSessionGUID();
if(x == Infinity) console.log(x); }
}
记录61e93284
或1413e390
这些值是有效数字,对于数字类型而言它们太大了,所以当它们被解释为数字时,它们会被转换为无穷大。
如果在测试中将==
替换为===
,则不会发生任何转换,也不会记录任何内容。转换是由==
运算符引起的。
答案 4 :(得分:0)
如果你真的需要数字类型,你总是可以使用以下
console.log(Number("1"));