在JavaScript中领先零

Hei*_*sis 8 javascript

试试这个:

var num = 040;
console.log(num); // 32
Run Code Online (Sandbox Code Playgroud)

从什么时候开始40 = 32?

Flo*_*ian 13

使用前导零,数字被解释为八进制,4*8 = 32.


Ori*_*iol 8

TL; DR

它被视为八进制(基数为8),因为它的前导0,就像一个前导0x会使它成为十六进制(基数为16).这有着漫长而折磨的历史,不再是现代JavaScript中如何编写八进制数字.在使用严格模式的现代JavaScript中,"遗留"八进制格式是语法错误; 八进制数用0o前缀写.

历史

早期(使用Netscape的初始语言以及第一和第二个ECMAScript规范),0数字文字的前导正式意味着八进制(基数为8),正如0x十六进制(基数16)的主要方式:

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit
Run Code Online (Sandbox Code Playgroud)

例如10,0120xA在写十进制数十个所有的方法.这与其他一些语言类似于JavaScript(C,C++,Java,...)的语言保持一致,但它非常令人困惑.

从ECMAScript 3开始,这种形式的八进制文字被降级为可选扩展名,并且十进制整数文字被更改,因此它们不能有前导零(除非实现包含扩展名):

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)
Run Code Online (Sandbox Code Playgroud)

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

一致性实现,在处理时严格模式代码(见10.1.1) ,必须不延伸的语法NumericLiteral包括OctalIntegerLiteral如描述B.1.1.

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

  • BinaryIntegerLiteral,前缀为0b0B.
  • OctalIntegerLiteral,前缀为0o0O.
  • HexIntegerLiteral,以0x或为前缀0X.

旧的OctalIntegerLiteral扩展已重命名为LegacyOctalIntegerLiteral,仍然允许在非严格模式下使用.

结论

因此,如果要解析基数为8的数字,请使用0o0O前缀(旧浏览器不支持)或使用parseInt.

如果您想确保您的数字将在基数10中解析,请删除前导零或使用parseInt.

例子

  • 010
    • 在严格模式下(需要ECMAScript 5),这是一个语法错误.
    • 在非严格模式下,它可能是语法错误或返回8(依赖于实现).
  • 0o10, 0O10
    • 在ECMAScript 6之前,它们是语法错误.
    • 在ECMAScript 6中,他们返回8.
  • parseInt('010', 8)
    • 它回来了8.
  • parseInt('010', 10)
    • 它回来了10.

如果您有兴趣,可以在这里找到当前的生活规格,以及这里的历史版本.


Ale*_*ler 5

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