JavaScript的parseInt函数为什么默认使用八进制?

23

JavaScript 的 parseInt 函数在输入字符串以 0 开头时默认将进制设为 8,这让我感到烦恼,因为我经常忘记传递可选的第二个参数,即十进制基数。我希望有人能告诉我,为什么将进制默认设为 8 是有道理的。

3个回答

34

2
是的。这很愚蠢、邪恶、糟糕和讨厌——仅仅因为之前的编程语言这样做了,所以实现了这个设计不良的“特性”。 - Matt Ball
2
一元的 + 操作符比使用 Number 更好。一元的 + 操作符忽略八进制格式(但仍然支持十六进制格式),并且比函数调用更快。 - Reid
2
@Reid:更好的选择取决于你的使用情况。至于性能,我不确定+是否更快(而且对于所有浏览器来说几乎肯定不是相同的)。让我们看看:http://jsperf.com/string-to-int-2 - Matt Ball
C(++) 从什么时候开始有 parseInt 函数?显然,这只是整数文字的一个方面(在 ECMAScript 5 被删除之前),而 parseInt 的行为则是另一回事。 - Stewart
@MattBall,你的回答没有提到整数字面量是如何解释的,因此你的“This”是一个悬空引用。 - Stewart
显示剩余2条评论

9
如果一个数字以0开头并且包含0到7之间(包括0和7)的数字,则它被解释为八进制数(使用8进制而不是10进制)。
然而,在parseInt中,如果一个字符串以0开头,它总是被解释为八进制,并在遇到无效字符时停止搜索(例如数字8或9或像z这样的字符)。
parseInt("070");     //56
parseInt("70");      //70
parseInt("070", 10); //70
parseInt("78");      //78
parseInt("078");     //7, because it stops before 8

如果您需要将一个字符串转换为数字,并且确定它不包含无效字符或小数部分,那么可以将其乘以1来使其成为数字:
1 * "070";           //70

我个人更喜欢这种方法,并认为它比调用函数更快。


2
对于那些不理解Matt Ball在说什么的人,第一个提交的答案只包含了第一段。 - Lekensteyn
1
现在所有这些都已经过时了。以前,以0开头的整数字面量被标记为八进制,但现在已经不合法(请参见我对Matt答案的评论)。但是我被告知,parseInt的这种行为从未成为标准的一部分,现在标准规定带有一个参数的parseInt始终使用十进制。 - Stewart

5

现在,几年后,parseInt()似乎可以正常处理以0开头的数字。当前浏览器:

parseInt("019"); // 19 on Firefox 67
parseInt("019"); // 19 on Chrome 75
parseInt("019"); // 19 on Safari 12
parseInt("019"); // 19 on IE 11
parseInt("019"); // 19 on Edge 42

但是,这个“修复”必然会破坏依赖parseInt("019")返回10而不是19的旧脚本...


Number.parseInt 也适用吗? - sandstrom
1
“019”包含数字9,因此它本身就不是有效的八进制数,这是否有任何影响?MDN使用了“015”的例子,但我不知道所有数字都低于8是否具有重要意义。 - Tim
1
@Tim,即使在Firefox和Chrome上,015似乎现在也作为十进制工作。我相信这是一个比较近期的变化,因为一两年前我仍然受到它的影响(或者可能是node.js?现在在v12.20+上也可以正常工作)。 - fireattack

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