Pregunta

Trate de ejecutar el siguiente en JavaScript:

parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!

acabo de aprender la manera dura que JavaScript cree que el cero indica una octal número entero , y ya que no hay "8" o "9" en base 8, la función devuelve cero. Nos guste o no, esto es por diseño .

¿Cuáles son las soluciones?

Nota:. Para mayor abundamiento, estoy a punto de publicar una solución, pero es una solución que no me gusta, así que por favor, puesto otros mejores respuestas /


Actualización:

La quinta edición de la norma JavaScript ( ECMA-262 ) introduce un cambio importante que elimina este comportamiento. Mozilla tiene una buena escritura .

¿Fue útil?

Solución

Este es un Gotcha Javascript común con una solución sencilla:

especificar la base , o radix ', así:

parseInt('08',10); // 8

También es posible usar Número :

Number('08'); // 8

Otros consejos

Si saber su valor estará en el rango entero de 32 bits, entonces ~~x va a hacer lo correcto en todos los escenarios.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

Si usted mira para arriba binario no (~), la especificación requiere una conversión "ToInt32" para el argumento que hace la conversión obvio para un Int32 y se especifica para coaccionar NaN valores a cero.

Sí, esto es increíblemente hacker, pero es tan conveniente ...

Desde el documentación parseInt , utilice el argumento radix opcional para especificar base 10:

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

Esto me parece pedante, confuso y prolijo (en realidad, un argumento adicional en cada parseInt?), Así que estoy esperando que hay una mejor manera.

function parseDecimal(s) { return parseInt(s, 10); }

editar: hacer su propia función, para hacer lo que realmente quiere, es sólo una opción si no te gusta la adición de la" 10" todo el tiempo a la llamada parseInt (). Tiene la desventaja de ser una función no estándar:. Más conveniente para usted si lo usa mucho, pero tal vez más confuso para los demás

Especificar la base:

var number = parseInt(s, 10);

¿Sería muy malo para reemplazar parseInt con una versión que asume decimal si no tiene segundo parámetro? (Nota - no probado)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

¿Qué tal esto para decimal:

('09'-0) === 9  // true

('009'-0) === 9 // true
  

También, en lugar de utilizar parseFloat o parseInt, utilice el operador unario ( + ).

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

y por una buena medida

+"09.09"
// => 9.09

MDN Enlace

  

El operador de suma unaria precede a su operando y evalúa a su operando, pero los intentos de convertirlo en un número, si no lo está ya. A pesar de la negación unaria (-) también se puede convertir a los no números, más unario es la manera más rápida y preferido de convertir algo en un número , ya que no lleva a cabo ninguna otra operación en el número

Si usted ha hecho un montón de codificación ya con parseInt y no quiere añadir", 10" a todo, sólo puede anular la función de hacer de base 10 el valor por defecto:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

Esto puede confundir a un lector más adelante, así que hacer una función parseInt10 () podrían ser más fáciles de entender. Personalmente prefiero utilizar una función simple de tener que añadir", 10" todo el tiempo - sólo crea más oportunidades de errores

.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top