web-dev-qa-db-ja.com

019がJavaScript構文エラーではないのはなぜですか?または、なぜ019> 020

JavaScriptコンソールで019 > 020と入力すると(ChromeとFirefoxの両方でテスト済み)、答えはtrueになります。

これは、020OctalIntegerLiteral16に等しい)として解釈されているのに対し、019は明らかに DecimalLiteral (そして19に等しい)。 1916より大きいため、019 > 020trueです。

私が困惑しているのは、そもそも019DecimalLiteralとして解釈される理由です。それはどの作品ですか? DecimalIntegerLiteral019を許可しません:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt

OctalIntegerLiteral019を許可しません(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 を開発しており、仕様とその逸脱に特別な注意を払う必要があります。 )

78
lexicore

私が見つけたものから、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

したがって、01LegacyOctalLikeDecimalIntegerLiteral(3)です。その場合、019NonOctalDecimalIntegerLiteral(2)であり、これはDecimalIntegerLiteral(1)です。

52
abl