在JavaScript中领先零

尝试这个:

<script language="javascript"> var iTest=040; alert(iTest); </script> 

从什么时候开始是40 = 32?

前导零,数字被解释为八进制和4 * 8 = 32。

因为0前缀表示八进制数(基数8)。

TL; DR

它被视为八进制数(基数为8),因为前导0 ,就像前导的0x会使其hex(基数为16)一样。 这有一个漫长而折磨的历史,不再是如何编写现代JavaScript的八进制数字。 在使用严格模式的现代JavaScript中,“传统”八进制格式是语法错误; 八进制数字是用0o前缀编写的。

历史

早期(以Netscape的初始语言以及第一和第二ECMAScript规范),数字文本中的前导0正式表示八进制 (基数为8),正如前导的0x表示hex(基数为16):

 OctalIntegerLiteral :: 0 OctalDigit OctalIntegerLiteral OctalDigit 

例如, 0120xA都是写十进制数的方法。 这与其他一些与JavaScript(C,C ++,Java,…)语法相似的语言保持一致,但是这种语言非常混乱。

从ECMAScript 3开始,八进制文本的forms被降级为一个可选的扩展,并且十进制整数文字被改变了,所以它们不能有前导零(除非实现包含扩展):

 DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits(opt) 

但ECMAScript 5禁止在严格模式下执行此操作:

符合的实现在处理严格模式代码(见10.1.1)时 ,不得扩展NumericLiteral的语法,使其包含如B.1.1所述的OctalIntegerLiteral

ECMAScript 6 (ECMAScript 2015)引入了BinaryIntegerLiteralOctalIntegerLiteral ,所以现在我们有更多连贯的文字:

  • BinaryIntegerLiteral ,前缀为0b0B
  • OctalIntegerLiteral ,以0o0O为前缀。
  • HexIntegerLiteral ,前缀为0x0X

旧的OctalIntegerLiteral扩展名已经改名为LegacyOutIntegerLiteral ,但仍然允许在非严格模式下使用。

结论

因此,如果你想parsing一个基数为8的数字,可以使用0o0O前缀(旧的浏览器不支持),或者使用parseInt

如果你想确保你的数字将以10为基础进行parsing,请删除前导零或使用parseInt

例子

  • 010
    • 在严格模式下(需要ECMAScript 5),这是一个语法错误。
    • 在非严格模式下,可能是语法错误或返回8 (实现相关)。
  • 0O10
    • 在ECMAScript 6之前,它们是语法错误。
    • 在ECMAScript 6中,它们返回8
  • parseInt('010', 8)
    • 它返回8
  • parseInt('010', 10)
    • 它返回10

如果你有兴趣,你可以在这里find当前的生活规范,以及这里的历史版本。