为什么 019 不是 JavaScript 语法错误?或者为什么 019 > 020

Why is 019 not a JavaScript syntax error? Or why is 019 > 020

如果我在 JavaScript 控制台中输入 019 > 020(在 Chrome 和 Firefox 中测试),我会得到答案 true.

这是因为 020 被解释为 OctalIntegerLiteral (equals 16) whereas 019 is apparently being interpreted as DecimalLiteral(并且等于 19)。由于 19 大于 16019 > 020true

令我困惑的是为什么 019 首先被解释为 DecimalLiteral。是哪个制作的? DecimalIntegerLiteral 不允许 019:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt

OctalIntegerLiteral 也不允许 019(因为 9 不是八进制数字):

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

OctalDigit :: one of
    0 1 2 3 4 5 6 7

所以从我在规范中看到的,019 实际上应该被拒绝,我不明白为什么它被解释为十进制整数。

我想这里有某种兼容性规则,但我没有找到正式的定义。谁能帮我解决这个问题?

(我为什么需要这个:我正在开发 JavaScript/ECMAScript parser for Java with JavaCC 并且必须特别注意规范 - 及其偏差。)

据我所知,JavaScript 的一些实现似乎在这一点上没有遵循规范。

来自MDN site:

Note that decimal literals can start with a zero (0) followed by another decimal digit, but If the next digit after the leading 0 is smaller than 8, the number gets parsed as an octal number. This won't throw in JavaScript, see bug 957513. See also the page about parseInt().

这仍然不能解释为什么 019 == 19,因为前导 0 之后的下一个数字是 1,因此应该将整数解析为八进制。但是引用的错误似乎确实与您的案例有关。它的描述说:

The following JavaScript program should throw an error:

08

As per the spec, DecimalIntegerLiteral can never be 0 directly followed by another decimal digit, although Chrome/Opera, PrestOpera, and Firefox do support it.

该错误已作为 WONTFIX

关闭

但是,根据下一版的草案,019 将是一个有效的十进制文字,其值等于 19:

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-additional-syntax-numeric-literals

(相关规则我已经标注)

The syntax and semantics of 11.8.3 is extended as follows except that 
this extension is not allowed for strict mode code:

[...]

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt
    NonOctalDecimalIntegerLiteral                         // (1)

NonOctalDecimalIntegerLiteral ::
    0 NonOctalDigit
    LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit    // (2)
    NonOctalDecimalIntegerLiteral DecimalDigit

LegacyOctalLikeDecimalIntegerLiteral ::
    0 OctalDigit                                          // (3)
    LegacyOctalLikeDecimalIntegerLiteral OctalDigit

所以 01LegacyOctalLikeDecimalIntegerLiteral (3) 。然后 019 是一个 NonOctalDecimalIntegerLiteral (2) 又是一个 DecimalIntegerLiteral (1).