¿Por qué 019 no es un error de sintaxis de JavaScript? O por qué es 019 > 020


Si escribo 019 > 020 en la consola JavaScript (probado en Chrome y Firefox), obtengo la respuesta true.

Esto se debe a que 020 se interpreta como un OctalIntegerLiteral (16) mientras que 019 aparentemente se interpreta como DecimalLiteral (y es igual a 19). Como 19 es mayor que 16, 019 > 020 is true.

Lo que me desconcierta es por qué 019 se interpreta como un DecimalLiteral en primer lugar. ¿Qué producción es? DecimalIntegerLiteral no permite 019:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt

OctalIntegerLiteral tampoco permite 019 (ya que 9 no es un dígito octal):

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

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

Así que de lo que veo en la especificación, 019 debería ser rechazado, no veo por qué se interpreta como un entero decimal.

Supongo que hay algún tipo de regla de compatibilidad en su lugar aquí, pero no he podido encontrar una definición formal. ¿Podría alguien ayudarme con esto?

(Por qué necesito esto: Estoy desarrollando un analizador JavaScript/ECMAScript para Java con JavaCC y tienen que prestar una atención especial a la especificación - y las desviaciones de la misma.)

Author: lexicore, 2015-01-24

1 answers

Por lo que pude encontrar, parece que algunas implementaciones de JavaScript simplemente no siguen las especificaciones en ese punto.

Del sitio MDN :

Tenga en cuenta que los literales decimales pueden comenzar con un cero (0) seguido de otro dígito decimal, pero si el siguiente dígito después del 0 inicial es menor que 8, el número se analiza como un número octal. Esto no agregue JavaScript, consulte error 957513. Ver también la página sobre parseInt ().

Esto todavía no explica por qué 019 == 19, dado que el dígito siguiente después del 0 inicial es 1 y el número entero debe analizarse como octal. Pero el error de referencia parece relacionado con su caso. Su descripción dice:

El siguiente programa JavaScript debería lanzar un error:

08

Según la especificación, DecimalIntegerLiteral nunca puede ser 0 directamente seguido de otro dígito decimal, aunque Chrome / Opera, PrestOpera, y Firefox hacer apóyalo.

El error se cierra como WONTFIX

Sin embargo, 019 sería un literal decimal válido, con valor igual a 19, según el borrador de la próxima edición:

Https://people.mozilla.org/~jorendorff/es6-draft.html#sec-additional-syntax-numeric-literals

(He marcado las reglas pertinentes)

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

Así que 01 es un LegacyOctalLikeDecimalIntegerLiteral (3) . Entonces 019 es un NonOctalDecimalIntegerLiteral (2) que a su vez es un DecimalIntegerLiteral (1).

 52
Author: abl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-24 16:58:51