Por qué JavaScript trata un número como octal si tiene un cero a la izquierda

Resuelto Jagajit Prusty asked hace 8 años • 3 respuestas
var x = 010;
console.log(x); //8

El motor JS convierte el número xen número octal. ¿Por qué sucede? ¿Cómo puedo prevenirlo?

Jagajit Prusty avatar May 03 '16 19:05 Jagajit Prusty
Aceptado

Creo que mi respuesta aquí responde a la pregunta, pero la pregunta no es exactamente un duplicado, por lo que incluyo una copia de mi respuesta.

Historia

El problema es que los literales enteros decimales no pueden tener ceros a la izquierda:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)

Sin embargo, ECMAScript 3 permitió (como extensión opcional) analizar literales con ceros a la izquierda en base 8:

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

Pero ECMAScript 5 prohibió hacer eso en modo estricto:

Una implementación conforme, al procesar código en modo estricto (ver 10.1.1) , no debe extender la sintaxis de NumericLiteral para incluir OctalIntegerLiteral como se describe en B.1.1 .

ECMAScript 6 presenta BinaryIntegerLiteral y OctalIntegerLiteral , por lo que ahora tenemos literales más coherentes:

  • BinaryIntegerLiteral , con el prefijo 0bo 0B.
  • OctalIntegerLiteral , con el prefijo 0oo 0O.
  • HexIntegerLiteral , con el prefijo 0xo 0X.

La antigua extensión OctalIntegerLiteral pasó a llamarse LegacyOctalIntegerLiteral , que todavía está permitida en modo no estricto.

Conclusión

Por lo tanto, si desea analizar un número en base 8, utilice los prefijos 0oo 0O(no admitidos por navegadores antiguos) o utilice parseInt.

Y si quiere estar seguro de que sus números se analizarán en base 10, elimine los ceros iniciales o utilice parseInt.

Ejemplos

  • 010
    • En modo estricto (requiere ECMAScript 5), arroja.
    • En modo no estricto, puede lanzar o devolver 8(depende de la implementación).
  • 0o10,0O10
    • Antes de ECMAScript 6, lanzaban.
    • En ECMAScript 6, devuelven 8.
  • parseInt('010', 8)
    • Vuelve 8.
  • parseInt('010', 10)
    • Vuelve 10.
Oriol avatar May 03 '2016 12:05 Oriol

Esto se debe a que algunos motores de JavaScript interpretan los ceros a la izquierda como literales de números octales. Está definido en un apéndice de la especificación ECMAScript .

Sin embargo, en modo estricto, las implementaciones conformes no deben implementar eso; consulte la especificación ECMAScript nuevamente:

Una implementación conforme, al procesar código en modo estricto (véase 10.1.1), no debe ampliar la sintaxis de NumericLiteral para incluir OctalIntegerLiteral como se describe en B.1.1.

Debido a esta ambigüedad, es mejor no utilizar ceros a la izquierda.

Ondra Žižka avatar May 03 '2016 12:05 Ondra Žižka