Javascript parseInt () con ceros a la izquierda

120

La función parseInt de Javascript no parece funcionar por completo.

parseInt("01") returns 1
parseInt("02") returns 2
parseInt("03") returns 3
parseInt("04") returns 4
parseInt("05") returns 5
parseInt("06") returns 6
parseInt("07") returns 7
parseInt("08") returns 0
parseInt("09") returns 0

No puedes explicar eso. Darle una oportunidad. (jsFiddle)

Editar Dado que esta pregunta fue formulada y respondida, la "función" de usar de forma predeterminada la base octal ha quedado obsoleta. [ 1 ] [ 2 ]

salvador
fuente
29
debes estar bromeando
georg
6
You can't explain that. Sí, puedes => developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Rocket Hazmat
3
Desde edades, cualquier número que comience con 0 representa OCTAL y 0x representa Hexa-Decimal. Creo que esto es universal para todos los idiomas, pero nuevamente puedo estar equivocado.
Selvakumar Arumugam
3
FYI: jsFiddle , es un mejor probador de JavaScript en línea que w3schools.com/jsref/tryit.asp .
Rocket Hazmat
2
@JohnHartsock Sí, es porque ambos estábamos en esta publicación stackoverflow.com/questions/8761997/…
savinger

Respuestas:

181

Esto se debe a que si un número comienza con un '0', se trata como base 8 (octal).

Puede forzar la base pasando la base como segundo parámetro.

parseInt("09", 10) // 9

Según los documentos , el segundo parámetro es opcional, pero no siempre se asume que sea 10, como puede ver en su ejemplo.

Cohete Hazmat
fuente
1
sí, pero si se asume octal, debería devolver 11 por 09 en lugar de 0.
Peeyush Kushwaha
2
@PeeyushKushwaha: Al revés. 11en base 8 está 9en base 10. 09no es un número de base 8 válido.
Rocket Hazmat
Pero quiero 09 después de parseInt, ¿hay alguna forma de
evitarlo?
39

Las llamadas a parseIntsiempre deben especificar una base en el segundo argumento:

parseInt("08", 10);

Las versiones anteriores de JavaScript tratan las cadenas que comienzan con 0octal (cuando no se especifica una base) y ni 08ni 09son números octales válidos.

De la documentación de Mozilla :

Si radix no está definido o es 0, JavaScript asume lo siguiente:

  • Si la cadena de entrada comienza con "0x" o "0X", la base es 16 (hexadecimal).
  • Si la cadena de entrada comienza con "0", la base es ocho (octal). Esta característica no es estándar y algunas implementaciones deliberadamente no la admiten (en su lugar, utilizan el radix 10). Por esta razón, siempre especifique una base cuando use parseInt .
  • Si la cadena de entrada comienza con cualquier otro valor, la base es 10 (decimal).

Si el primer carácter no se puede convertir en un número, parseInt devuelve NaN.

Y del estándar ECMAScript 3 :

Cuando la base es 0 o no está definida y el número de la cadena comienza con un dígito 0 no seguido por una x o una X , entonces la implementación puede, a su discreción, interpretar el número como octal o decimal. Se anima a las implementaciones a interpretar los números en este caso como decimales.

La última versión de JavaScript ( ECMAScript 5 ) abandona este comportamiento , pero aún debe especificar la base para satisfacer los navegadores más antiguos.

Wayne
fuente
Dado que esto está en desuso, en el futuro estaría bien con el uso de ceros a la izquierda, ¿no es así?
Pacerier
15

Hay un parámetro Radix

parseInt(value, base)

Donde base es la raíz.

En este caso, está evaluando números base10 (decimales), por lo tanto, use

parseInt(value, 10);
John Hartsock
fuente
4

Esto no parece ser completamente válido en los nuevos navegadores. Internet Explorer 9 y 10 devolverán 8 si ejecuta 'parseInt ("08")' mientras que Internet Explorer 8 y versiones anteriores devolverán 0 (IE10 en modo peculiar también devolverá 0).

La última versión de Chrome también devuelve 8, por lo que deben haber cambiado la interpretación recientemente.

Maffelu
fuente
Sí, el comportamiento ha cambiado. Actualizaré mi respuesta. developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne
1
Sí, la última versión de Firefox y Chrome no tiene ningún problema ahora.
mythicalcoder
3

Este problema está obsoleto ahora. Pero aún puede usar radix in parseIntpara convertir el número de otras bases en base-10. P.ej,

var baseTwoNumber = parseInt('0010001', 2);

devuelve 17(que es base 10 de 0010001).

Muhammad Imran
fuente
0

Sugerencia: como ya sabe, cuándo se ha desaprobado el uso predeterminado de octal. Así es como lo solucionaría en navegadores heredados

// ES-5 15.1.2.2
if (parseInt('08') !== 8 || parseInt('0x16') !== 22) {
    parseInt = (function (origParseInt) {
        var hexRegex = /^0[xX]/;
        return function parseIntES5(str, radix) {
            str = String(str).trim();
            if (!Number(radix)) {
                radix = hexRegex.test(str) ? 16 : 10;
            }
            return origParseInt(str, radix);
        };
    }(parseInt));
}
Sin fin
fuente
PD: si usa solo un número constante con un cero a la izquierda (en lugar de una cadena), todavía se trata como base 8 en todos los navegadores actuales.
Agamemnus
0

El problema parece haber cambiado ahora en la mayoría de los navegadores.

Firefox 51.0.1 (64 bits)

parseInt("09")   // 9

Chrome 55.0.2883.95 (64 bits)

parseInt("09")   // 9

Safari 10.0 (12602.1.50.0.10)

parseInt("09")   // 9

=====

Práctica recomendada

Habiendo dicho eso, solo para estar en el lado más seguro y evitar problemas, use el parámetro base / radix como se sugiere en la respuesta aceptada .

parseInt("09", 10)    // 9

Prueba adicional

Solo quería probar esto también, si el argumento no es una cadena. Chrome y Safari dan un resultado exacto. Firefox también devuelve el resultado adecuado, pero con una advertencia.

parseInt(09)     // 9. (Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant)
codificador mítico
fuente
Si el valor comienza con 0 y es un número, parseInt seguirá usando la base 8. Pruebe parseInt (020)
sirrocco
Si. Incluso he señalado la respuesta sugerida. Y conozco las mejores prácticas y las malas funciones que debo evitar. Así que también he dado práctica recomendada en mi respuesta.
mythicalcoder