【问题标题】:Why JavaScript treats a number as octal if it has a leading zero为什么 JavaScript 将一个数字视为八进制,如果它有一个前导零
【发布时间】:2016-08-28 11:27:15
【问题描述】:
var x = 010;
console.log(x); //8

JS 引擎将数字x 转换为八进制数字。为什么会发生?如何预防?

【问题讨论】:

  • @Andy - 10,而不是 8。他问为什么在数字前加上 0 会使它假定它是八进制。我不怪他问。
  • 以 0 开头的文字数值总是被解释为八进制值。
  • 哈,是的,我没有正确地问这个问题。我知道为什么它将它记录为八进制,我只是想知道 10 是否是 OP 的预期输出。
  • 这是严格模式下禁止的非标准做法。见Leading zero in javascript
  • 如果我们在一个数字前面加上 0x 那么它也会把这个数字转换成十六进制

标签: javascript


【解决方案1】:

我认为我的回答 here 回答了这个问题,但这个问题并不完全是重复的,所以我附上了我的回答的副本。

历史

问题是十进制整数文字不能有前导零:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)

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

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

但是ECMAScript 5 禁止在严格模式下这样做:

在处理strict mode code (see 10.1.1) 时,符合规范的实现不得扩展NumericLiteral 的语法以包括B.1.1 中所述的OctalIntegerLiteral

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

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

旧的 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

【讨论】:

    【解决方案2】:

    这是因为一些 JavaScript 引擎将前导零解释为八进制数字文字。在ECMAScript specification的附录中定义。

    但是,在严格模式下,符合要求的实现不得实现 - 再次参见 ECMAScript specification

    在处理严格模式代码时符合规范的实现(参见 10.1.1),不得将 NumericLiteral 的语法扩展为包含 B.1.1 中所述的 OctalIntegerLiteral。

    由于这种歧义,最好不要使用前导零。

    【讨论】:

    • 这不是 JS 字面量的语法。这是在严格模式下明确禁止的不鼓励的非标准扩展。
    • 对 :) 从来没有注意到。让我给这个问题+1。答案固定。
    【解决方案3】:

    JS 将前导零的数字视为八进制,如果它们有效八进制,则将其视为十进制。为防止这种情况,请不要在源代码中使用前导零

    console.log(010, 10, +"010")
    
    if (021 < 019) console.log('Paradox');

    或使用strict mode 不允许使用前导零

    'use strict'
    
    if (021 < 019) console.log('Paradox');

    【讨论】:

    • “未捕获的语法错误:严格模式下不允许使用前导零的小数。”
    猜你喜欢
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 2021-12-25
    • 2013-08-01
    • 1970-01-01
    相关资源
    最近更新 更多