Почему 019 не является синтаксической ошибкой JavaScript? Или почему 019> 020


если я типа 019 > 020 в консоли JavaScript (проверено как в 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 не восьмеричная цифра):

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

OctalDigit :: one of
    0 1 2 3 4 5 6 7

Итак, из того, что я вижу в спецификации,019 на самом деле должен быть отклонен, я не понимаю, почему он интерпретируется как десятичное целое число.

я думаю, что здесь есть какое-то правило совместимости, но я не смог найти формальное определение. Может ли кто-нибудь помочь мне это?

(зачем мне это нужно: я разрабатываю JavaScript / ECMAScript парсер для Java с JavaCC и должны обратить особое внимание на спецификацию-и отклонения от нее.)

1 78

1 ответ:

из того, что я мог найти, кажется, что некоторые реализации JavaScript просто не следуют спецификации по этому вопросу.

С сайт MDN:

обратите внимание, что десятичные литералы могут начинаться с нуля (0), а затем еще одна десятичная цифра, но если следующая цифра после ведущей 0 меньше 8, число анализируется как восьмеричное число. Это не бросьте в JavaScript, см. ошибка 957513. Смотрите также страницу о parseInt().

это все еще не объясняет, почему 019 == 19, учитывая, что следующая цифра после ведущего 0 равна 1 и поэтому все число должно быть проанализировано как восьмеричное. Но упомянутая ошибка, похоже, связана с вашим делом. Его описание гласит:

следующая программа 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).