如果我在JavaScript控制台中输入019 > 020
(在Chrome和Firefox中测试过),我会得到答案true
。
这是因为020
被解释为OctalIntegerLiteral
(等于16
),而019
显然被解释为DecimalLiteral
(等于{{ 1}})。由于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
实际上应该被拒绝,我不明白为什么它被解释为十进制整数。
我想这里有某种兼容性规则,但我找不到正式的定义。可以请任何人帮助我吗?
(为什么我需要这个:我开发JavaScript/ECMAScript parser for Java with JavaCC并且必须特别注意规范 - 以及它的偏差。)
答案 0 :(得分:52)
根据我的发现,似乎JavaScript的某些实现不符合该点的规范。
请注意,十进制文字可以以零(0)开头,后跟 另一个十进制数字,但如果前导0之后的下一个数字是 小于8时,该数字被解析为八进制数。这不会 扔进JavaScript,请参阅bug 957513。另请参阅有关的页面 parseInt函数()。
这仍然无法解释为什么019 == 19
,因为前导0之后的下一个数字是1,因此整数应该被解析为八进制。但引用的bug似乎与您的案例有关。它的描述说:
以下JavaScript程序应该抛出错误:
08
根据规范,
DecimalIntegerLiteral
永远不能直接0
然后是另一个十进制数字,虽然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
所以01
是LegacyOctalLikeDecimalIntegerLiteral
(3)。然后019
是NonOctalDecimalIntegerLiteral
(2),而DecimalIntegerLiteral
(1)又是{{1}}。