如果我在JavaScript控制台中输入019 > 020
(已在Chrome和Firefox中进行了测试),则会得到true
的答案。
这是由于020
被解释为 OctalIntegerLiteral
(等于16
),而019
显然被解释为 DecimalLiteral
(并等于19
)。由于19
大于16
,因此019 > 020
是true
。
令我感到困惑的是,为什么首先将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
因此
01
是LegacyOctalLikeDecimalIntegerLiteral
(3)。那么019
是NonOctalDecimalIntegerLiteral
(2),它又是DecimalIntegerLiteral
(1)。