在JavaScript中:为什么parseInt("08")的结果为零,但是parseInt(08)的结果正确?

3

可能重复:
JavaScript parseInt八进制漏洞的解决方法

我认为这与八进制解析有关,因为它只在8或9上发生。也有人认为这是Chrome的错误,但Firefox中也可以复制。

这是故意的行为吗?如果是,为什么?


我的猜测是parseInt接受一个字符串参数,如果你传递的是08(它是数字类型),它会首先将其转换为没有前导零的字符串。尝试在控制台中输入-(08+''),你会发现得到的是"8"而不是"08",这意味着它运行了parseInt("8") - 这是一个十进制转换。 - yoavmatchulsky
3个回答

12

这里的解决方案很简单。永远不要在调用parseInt()时没有指定期望的进制。当你不传递第二个参数时,parseInt()会试图根据数字格式猜测进制。但是它经常猜错。

像这样指定进制,你将得到预期的结果:

parseInt("08", 10) == 8;
关于猜测规则,您可以参考MDN 对 parseInt() 的文档页面
如果 radix 未定义或为 0,则 JavaScript 会假定以下内容:
- 如果输入字符串以 "0x" 或 "0X" 开头,则 radix 为 16(十六进制)。 - 如果输入字符串以 "0" 开头,则 radix 为 8(八进制)。此功能不是标准的,并且某些实现故意不支持它(而使用 radix 10)因此,使用 parseInt 时总是要指定一个 radix 。 - 如果输入字符串以任何其他值开头,则 radix 为 10(十进制)。如果第一个字符不能转换为数字,则 parseInt 返回 NaN。
因此,根据这些规则,parseInt()会猜测"08"是八进制,但然后它遇到了一个在八进制中不被允许的数字,所以返回0
当您将一个数字传递给parseInt()时,它无事可做,因为该值已经是一个数字,所以它不会尝试更改它。

5

"这是故意的行为吗?"

是的。

"如果是,为什么?"

在规范中,前导的0是表示八进制数字的符号。在八进制计数中,不存在符号8和9,因此parseInt使用它发现的第一个有效数字,即0。

如果您要...

parseInt('123@xq$_.f(--_!2*')

......结果将是......

123

因为在字符串开头发现了一个有效的数字,所以该字符串后面的任何无效内容都将被忽略。


我知道在八进制中它们不存在,但为什么一个字符串会被 parseInt() 解释为八进制,而数字却不会? - Bryan Agee
文字字面上的“08”只是数字8。 - Alex K.

0
你可以这样修复它:
parseInt("080".replace(/^[0]+/g,""));

我确实使用了这种黑科技 { data.replace(/^0+/,'') } 来应对排序问题,但想知道它为什么会那样。 - Bryan Agee
3
为什么要这样做,当你可以将基数传递给 parseInt 函数,它会为你完成正确的事情呢? - jfriend00
没错,我每天都在学习 :-) - Alytrem
这很危险。相反(如上所述),使用 parseInt('08', 10)。如果 '08' 存储在一个变量中,该变量可以是字符串或整数,并且您希望每个变量按预期工作,则应将其传递给具有正确基数的 parseInt。此外,这更易读。 - Marshall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接