Javascript parseInt()前导零


119

Javascript的parseInt函数似乎无法完全正常工作。

parseInt("01") returns 1
parseInt("02") returns 2
parseInt("03") returns 3
parseInt("04") returns 4
parseInt("05") returns 5
parseInt("06") returns 6
parseInt("07") returns 7
parseInt("08") returns 0
parseInt("09") returns 0

你无法解释。试试看。(jsFiddle)

编辑自从询问并回答了此问题以来,默认为八进制基数的“功能”已被弃用。[ 1 ] [ 2 ]


28
你一定是在开玩笑
georg

6
You can't explain that. 是的,你可以=> developer.mozilla.org/en/JavaScript/Reference/Global_Objects/...
火箭防化

3
由于年龄的增长,任何以0开头的数字都代表OCTAL,而0x则代表十六进制十进制。我相信这对所有语言都是通用的,但我可能还是错了。
Selvakumar Arumugam 2012年

3
仅供参考:jsFiddle是比w3schools.com/jsref/tryit.asp更好的在线JavaScript测试器。
火箭Hazmat 2012年

2
@JohnHartsock叶,那是因为我们都对这个职位stackoverflow.com/questions/8761997/...
savinger

Answers:


180

这是因为,如果数字以“ 0”开头,则将其视为基数8(八进制)。

您可以通过将base作为第二个参数来强制使用base。

parseInt("09", 10) // 9

根据docs,第二个参数是可选的,但并不总是假定它为10,如您从示例中看到的那样。


1
是的,但如果它假设八进制,应该为0。09,而不是返回11
Peeyush Kushwaha

2
@PeeyushKushwaha:其他方法。 11以8为9底的10 09是以10 为底的有效数字。
火箭Hazmat

但是我想在parseInt之后
加上

39

调用parseInt时应始终在第二个参数中指定一个底数:

parseInt("08", 10);

早期版本的JavaScript 0将以八进制开头的字符串(未指定基数的情况下)视为字符串,08也不09是有效的八进制数字。

从Mozilla 文档中

如果未定义radix或0,则JavaScript假定以下内容:

  • 如果输入字符串以“ 0x”或“ 0X”开头,则基数为16(十六进制)。
  • 如果输入字符串以“ 0”开头,则基数为八(八进制)。此功能是非标准的,某些实现故意不支持此功能(而是使用基数10)。因此,在使用parseInt时始终指定一个基数
  • 如果输入字符串以任何其他值开头,则基数为10(十进制)。

如果第一个字符不能转换为数字,则parseInt返回NaN。

根据ECMAScript 3标准:

当radix为0或未定义并且字符串的数字以0 开头而不是xX时,实现可以自行决定将数字解释为八进制还是十进制。在这种情况下,鼓励实现人员将数字解释为十进制。

最新版本的JavaScript(ECMAScript 5放弃了此行为,但是您仍应指定基数以满足较旧的浏览器。


由于不推荐使用此方法,将来您可以使用前导零来解决问题,不是吗?
Pacerier,2015年

15

有一个基数参数

parseInt(value, base)

基数是基数。

在这种情况下,您正在评估base10(十进制)数字,因此请使用

parseInt(value, 10);

4

在新的浏览器中,这似乎并不完全有效。如果执行'parseInt(“ 08”)',则Internet Explorer 9和10将返回8,而Internet Explorer 8和以前的版本将返回0(古怪模式下的IE10也将返回0)。

最新版本的Chrome也返回8,因此它们必须最近更改了解释。


是的,行为已更改。我将更新我的答案。developer.mozilla.org/en-US/docs/JavaScript/Reference/…–
韦恩(Wayne),

1
是的,Firefox和Chrome的最新版本现在没有问题。
mythicalcoder

3

现在已弃用此问题。但是您仍然可以使用基数输入parseInt将其他数量的基数转换为10基数。例如,

var baseTwoNumber = parseInt('0010001', 2);

返回17(以的10为底0010001)。


0

提示:现在您已经知道何时不建议使用默认八进制。这是在旧版浏览器中修复它的方法

// ES-5 15.1.2.2
if (parseInt('08') !== 8 || parseInt('0x16') !== 22) {
    parseInt = (function (origParseInt) {
        var hexRegex = /^0[xX]/;
        return function parseIntES5(str, radix) {
            str = String(str).trim();
            if (!Number(radix)) {
                radix = hexRegex.test(str) ? 16 : 10;
            }
            return origParseInt(str, radix);
        };
    }(parseInt));
}

PS:如果您仅使用带有前导零(而不是字符串)的常数,则在所有当前浏览器中,该数字仍被视为以8为底。
Agamemnus

0

现在,大多数浏览器中的问题似乎已经改变。

Firefox 51.0.1(64位)

parseInt("09")   // 9

Chrome 55.0.2883.95(64位)

parseInt("09")   // 9

Safari 10.0(12602.1.50.0.10)

parseInt("09")   // 9

=====

推荐做法

话虽如此,为了更加安全和避免问题,请按照接受的答案中的建议使用base / radix参数。

parseInt("09", 10)    // 9

额外测试

如果参数不是字符串,我也想测试一下。Chrome和Safari可以提供准确的结果。Firefox也返回正确的结果,但带有警告。

parseInt(09)     // 9. (Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant)

如果该值以0开头并且是数字,则parseInt仍将使用基数8。尝试parseInt(020)
sirrocco

是。我什至指出了建议的答案。而且我知道最佳做法和应避免的不良功能。因此,我在回答中也给出了推荐做法
mythicalcoder
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.