Por qué JavaScript trata un número como octal si tiene un cero a la izquierda
var x = 010;
console.log(x); //8
El motor JS convierte el número x
en número octal. ¿Por qué sucede? ¿Cómo puedo prevenirlo?
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
0b
o0B
. - OctalIntegerLiteral , con el prefijo
0o
o0O
. - HexIntegerLiteral , con el prefijo
0x
o0X
.
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 0o
o 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
.
- Vuelve
parseInt('010', 10)
- Vuelve
10
.
- Vuelve
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.