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

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

这是因为020被解释为OctalIntegerLiteral(等于16),而019显然被解释为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,必须特别注意规范及其偏差。)


解决方案

据我所知,在这一点上,似乎有些实现并不符合规范。

来自MDN site:

请注意,十进制文字可以以零(0)开头,后跟 另一个十进制数字,但如果前导0之后的下一个数字是 小于8的数字将被解析为八进制数。这不会的 加上JavaScript,请参见bug 957513。另请参阅关于 ParseInt()。

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

以下JavaScript程序应抛出错误:

08
根据规范,DecimalIntegerLiteral绝不能直接 后跟另一个十进制数字,尽管Chrome/Opera、PrestOpera、 而Firefox确实支持它。

错误关闭为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)。

相关文章