如果我在JavaScript控制台中输入019 > 020(已在Chrome和Firefox中进行了测试),则会得到true的答案。

这是由于020被解释为 OctalIntegerLiteral (等于16),而019显然被解释为 DecimalLiteral (并等于19)。由于19大于16,因此019 > 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:



鉴于开头0后面的下一个数字为1,因此仍不能解释为什么019 == 19,因此应将整数解析为八进制。但是引用的错误似乎与您的情况有关。它的描述说:



该错误已作为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)。那么019NonOctalDecimalIntegerLiteral(2),它又是DecimalIntegerLiteral(1)。

10-07 12:56