JavaScript(ECMAScript)構文定義とレガシーコードとの戦い。本記事の内容はStack Overflowで見つけた質問と回答に基づく。
19 > 20 // false 019 > 020 // true
ホストがWebブラウザかつ非Strictモードに限って、019
は有効な10進数リテラルの値19、020
は8進数リテラルの値16と解釈される。ECMAScript 6ではWebブラウザ向け追加拡張として、上記レガシーコードを合法化する構文を形式的に定義している。*1
(PDF)Standard ECMA-262 6th Edition, B.1.1より一部引用。
019
はNonOctalDecimalIntegerLiteral、つまり01
→ LegacyOctalLikeDecimalIntegerLiteralと9
→NonOctalDigitに対応する。これはDecimalIntegerLiteralつまり10進数リテラルとして解釈される。020
はLegacyOctalIntegerLiteralに対応する。これは名前通り8進数リテラルとして解釈される。
The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.
B.1.1 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:Syntax
NumericLiteral ::
DecimalLiteral
BinaryIntegerLiteral
OctalIntegerLiteral
HexIntegerLiteral
LegacyOctalIntegerLiteralLegacyOctalIntegerLiteral ::
0
OctalDigit
LegacyOctalIntegerLiteral OctalDigitDecimalIntegerLiteral ::
0
NonZeroDigit DecimalDigitsopt
NonOctalDecimalIntegerLiteralNonOctalDecimalIntegerLiteral ::
0
NonOctalDigit
LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit
NonOctalDecimalIntegerLiteral DecimalDigitLegacyOctalLikeDecimalIntegerLiteral ::
0
OctalDigit
LegacyOctalLikeDecimalIntegerLiteral OctalDigitNonOctalDigit :: one of
8
9
ノート:Syntax定義中に登場するLegacyOctalIntegerLiteralやLegacyOctalLikeDecimalIntegerLiteralという名前がなんとも。
*1:同Annex B. Additional ECMAScript Features for Web Browsersは"normative"であり、ECMAScript言語仕様の一部として規定している。