Ответ 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), которое, в свою очередь, есть a DecimalIntegerLiteral
(1).