为什么 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
大于 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 的一些实现似乎在这一点上没有遵循规范。
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
所以 01
是 LegacyOctalLikeDecimalIntegerLiteral
(3) 。然后 019
是一个 NonOctalDecimalIntegerLiteral
(2) 又是一个 DecimalIntegerLiteral
(1).
如果我在 JavaScript 控制台中输入 019 > 020
(在 Chrome 和 Firefox 中测试),我会得到答案 true
.
这是因为 020
被解释为 OctalIntegerLiteral
(equals 16
) whereas 019
is apparently being interpreted as 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 的一些实现似乎在这一点上没有遵循规范。
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 be0
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
所以 01
是 LegacyOctalLikeDecimalIntegerLiteral
(3) 。然后 019
是一个 NonOctalDecimalIntegerLiteral
(2) 又是一个 DecimalIntegerLiteral
(1).