一尘不染

为什么JavaScript如果数字以前导零开头,则将其视为八进制

javascript

var x = 010;
console.log(x); //8

JS引擎将数字转换x为八进制数字。为什么会这样呢?我该如何预防?


阅读 859

收藏
2020-05-01

共1个答案

一尘不染

历史

问题在于十进制整数文字不能包含前导零:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)

但是,ECMAScript 3允许(作为可选扩展)解析以8为底的前导零的文字:

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

但是ECMAScript 5禁止以严格模式执行此操作:

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

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

  • BinaryIntegerLiteral ,以0b开头0B
  • OctalIntegerLiteral ,以0o开头0O
  • HexIntegerLiteral ,以0x开头0X

旧的 OctalIntegerLiteral 扩展名已重命名为 LegacyOctalIntegerLiteral ,但仍可以在非严格模式下使用。

结论

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

而且,如果您想确保自己的数字将以10为底进行解析,请删除前导零或使用parseInt

例子

  • 010
    • 在严格模式下(需要ECMAScript 5),它会抛出。
    • 在非严格模式下,它可能会抛出或返回8(取决于实现)。
  • 0o100O10
    • 在ECMAScript 6之前,它们会抛出。
    • 在ECMAScript 6中,它们返回8
  • parseInt('010', 8)
    • 它返回8
  • parseInt('010', 10)
    • 它返回10
2020-05-01