Why is 019 not a JavaScript syntax error? Or why is 019 > 020
From what I could find, it seems that some implementations of JavaScript just don't follow the spec on that point.
From the MDN site:
Note that decimal literals can start with a zero (0) followed by another decimal digit, but If the next digit after the leading 0 is smaller than 8, the number gets parsed as an octal number. This won't throw in JavaScript, see bug 957513. See also the page about parseInt().
This still doesn't explain why 019 == 19
, given that the next digit after the leading 0 is 1 and the whole number should therefore be parsed as octal. But the referenced bug does seem related to your case. Its description says:
The following JavaScript program should throw an error:
08
As per the spec,
DecimalIntegerLiteral
can never be0
directly followed by another decimal digit, although Chrome/Opera, PrestOpera, and Firefox do support it.
The bug is closed as WONTFIX
However, 019
would be a valid decimal literal, with value equal to 19, according to the draft of the next edition:
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-additional-syntax-numeric-literals
(I've marked the relevant rules)
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
So 01
is a LegacyOctalLikeDecimalIntegerLiteral
(3) . Then 019
is a NonOctalDecimalIntegerLiteral
(2) which in turn is a DecimalIntegerLiteral
(1).