1

我有这个代码:

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

为什么会这样?在这两种情况下,值都会更改为字符串。

4

5 回答 5

3

您正在生成十六进制字符串。

当您使用==运算符时,解释器会尝试将两个值强制转换为相同的数据类型。将字符串与 进行比较时Infinity,该中间数据类型为Number。当这些字符串包含字母“e”(一个有效的十六进制数字)并且它们被强制转换为 aNumber时,javascript 将其解释为 10^x ,最终成为一个巨大的数字。

Numberjavascript 中的 s 为 8 个字节,因此大于1.7976931348623157e308等于Infinity.

解决此问题的最简单方法是将您更改==为,===这样字符串就不会被强制转换为数字。

if(getSessionGUID() === Infinity)

http://jsfiddle.net/Uhkxm/

于 2012-11-14T19:14:54.720 回答
2

JavaScript 是动态类型的。没有整数,浮点数。字符串数据类型。所有这些转换都是根据上下文在内部完成的。

+ 可以是字符串连接或添加,具体取决于上下文。

编辑:道歉。太晚了。但在与无穷大进行比较时,是 == 执行转换为数字。在某些情况下,您生成了有效数字。

于 2012-11-14T18:54:16.730 回答
2

我想我想通了。除了我的测试代码外,所有这些实际上都没有错。

如果你使用这个字符串“11e51354”,你可以让它断言为真,因为 Javascript 会检查所有可以使它等于真的类型。

"11e51354" == Infinity # True

正确的测试是:

"11e51354" === Infinity # False

它仍然是一个字符串,但不知何故,当我通过 GET 请求发送它时,它被转换为一个给出 Infinity 的数字类型。

于 2012-11-14T19:06:12.970 回答
2

这个测试揭示了答案:

for (var i = 0; i < 100000; i++){
  var x=getSessionGUID();
  if(x == Infinity) console.log(x); }
}

它记录像61e932841413e390

这些值是有效数字,它们对于 Number 类型来说太大了,所以当它们被解释为数字时,它们会被强制转换为 Infinity。

如果您在测试中替换=====,则不会发生转换,也不会记录任何内容。转换是由==操作员引起的。

于 2012-11-14T19:11:09.993 回答
0

如果你真的需要一个数字类型,你总是可以使用以下。
console.log(Number("1"));

于 2012-11-14T18:57:15.537 回答