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
は8進数ではないため):
OctalIntegerLiteral ::
0 OctalDigit
OctalIntegerLiteral OctalDigit
OctalDigit :: one of
0 1 2 3 4 5 6 7
したがって、仕様にあることから、019
は実際には拒否されるべきであり、なぜそれが10進整数として解釈されるのかわかりません。
ここにはある種の互換性ルールがあると思いますが、正式な定義を見つけることができませんでした。誰かがこれを手伝ってくれませんか?
(これが必要な理由:私は JavaScript/ECMAScriptパーサーfor Java with JavaCC を開発しており、仕様とその逸脱に特別な注意を払う必要があります。 )
私が見つけたものから、JavaScriptのいくつかの実装はその点で仕様に従わないようです。
MDNサイト: から
10進リテラルは、ゼロ(0)で始まり、その後に別の10進数字が続く場合がありますが、先頭の0の後の次の数字が8より小さい場合、数値は8進数として解析されることに注意してください。これはJavaScriptをスローしません。 バグ95751 を参照してください。 parseInt()に関するページも参照してください。
これは、先頭の0の後の次の桁が1であり、したがって整数を8進数として解析する必要があることを考えると、なぜ019 == 19
なのかをまだ説明していません。しかし、参照されているバグはあなたのケースに関連しているようです。その説明は言う:
次のJavaScriptプログラムはエラーをスローするはずです:
08
仕様によると、Chrome/Opera、PrestOpera、Firefoxはサポートしていますが、
DecimalIntegerLiteral
の直後に別の10進数を0
することはできません。
バグはWONTFIXとしてクローズされます
ただし、次の版のドラフトによれば、019
は、値が19に等しい有効な10進リテラルになります。
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)です。