Convierte NaN a 0 en javascript

238

¿Hay alguna manera de convertir los valores de NaN a 0 sin una instrucción if:

if (isNaN(a)) a = 0;

Es muy molesto verificar mis variables cada vez.

Tamás Pap
fuente
44
¿No puedes simplemente convertirlo en una función?
the_drow
Esto es solo como 20 caracteres, ¿cuál es el problema?
Rusty Fausak
1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }y luego solonoNaN( a )
Šime Vidas
1
@rfausak Por lo general, no quieres repetirlo (ver SECO ). Si se necesita una cierta funcionalidad varias veces, se prefiere una función dedicada.
Šime Vidas

Respuestas:

575

Puedes hacerlo:

a = a || 0

... que convertirá un valor de "falsey" a 0.

Los valores de "falsey" son:

  • false
  • null
  • undefined
  • 0
  • "" ( cuerda vacía )
  • NaN ( No un número )

O esto si lo prefieres:

a = a ? a : 0;

... que tendrá el mismo efecto que el anterior.


Si la intención era probar algo más que solo NaN, entonces puede hacer lo mismo, pero primero haga una conversión a Número .

a = +a || 0

Esto usa el operador unario + para intentar convertir aa un número. Esto tiene el beneficio adicional de convertir cosas como cadenas numéricas '123'a un número.

Lo único inesperado puede ser si alguien pasa una matriz que se puede convertir con éxito en un número:

+['123']  // 123

Aquí tenemos una matriz que tiene un solo miembro que es una cadena numérica. Se convertirá con éxito a un número.

usuario113716
fuente
La idea de convertir la verificación en una función es buena, pero esta es más elegante.
Tamás Pap
1
@Bakudan: Buen punto. Estaba pensando que a OP solo le preocupaba el NaNvalor específico . Esto no funcionará como prueba para todos los valores no numéricos. Aunque podríamos intentar una conversión toNumber primero. Voy a actualizar
user113716
... ah, es por el título "Convertir NaN a 0" . De todos modos, cubierto en ambos sentidos ahora.
user113716
2
Gracias amigo, he seleccionado y modificado un poco esto para mí a = a * 1 || 0
Alguien
Increíble. Gracias
Apit John Ismail
32

Usar una doble tilde (NO bit a doble bit) ~~- hace algunas cosas interesantes en JavaScript. Por ejemplo, puede usarlo en lugar de Math.flooro incluso como una alternativa a parseInt("123", 10)! Se ha discutido mucho en la web, por lo que no explicaré por qué funciona aquí, pero si le interesa: ¿Cuál es el operador de "doble tilde" (~~) en JavaScript?

Podemos explotar esta propiedad de una doble tilde para convertir NaNa un número, ¡y felizmente ese número es cero!

console.log(~~NaN); // 0

WickyNilliams
fuente
1
Gracias, yo no sabía de esto ~~en absoluto, que sólo utilizamos a lo largo de lado con parseFloat()este modo: ~~parseFloat($variable);. Muy ordenado :) +1
Rens Tillmann
23

Escriba su propio método y úselo donde quiera que desee un valor numérico:

function getNum(val) {
   if (isNaN(val)) {
     return 0;
   }
   return val;
}
Saket
fuente
1
Si paso, nullentonces no me da el resultado esperado de 0. Más sobre mi punto aquí: stackoverflow.com/questions/115548/why-is-isnannull-false-in-js
Andrei Bazanov
2
Además de mi comentario anterior, terminé usando en su Number(val)lugar, ya que regresa 0cuando no puede resolverlo de todos modos.
Andrei Bazanov
4

Algo más simple y efectivo para cualquier cosa:

function getNum(val) {
   val = +val || 0
   return val;
}

... que convertirá un valor de "falsey" a 0.

Los valores de "falsey" son:

  • false
  • null
  • undefined
  • 0
  • "" ( cuerda vacía )
  • NaN ( No un número )
Woold
fuente
1
¡Interesante! Solo me pregunto cómo reacciona cuando val puede ser un valor negativo. Por lo que he probado, no hay nada de malo en esto, pero por si acaso ...
Luciano
2

En lugar de criticarlo para que pueda continuar, ¿por qué no retroceder y preguntarse por qué se encuentra con un NaN en primer lugar?

Si alguna de las entradas numéricas de una operación es NaN, la salida también será NaN. Así funciona el estándar actual de punto flotante IEEE (no es solo Javascript). Ese comportamiento es por una buena razón : la intención subyacente es evitar que use un resultado falso sin darse cuenta de que es falso.

La forma en que funciona NaN es que si algo sale mal en alguna sub-sub-sub-operación (produciendo un NaN en ese nivel inferior), el resultado final también será NaN, que reconocerá inmediatamente como un error incluso si su la lógica de manejo de errores (¿lanzar / atrapar, tal vez?) aún no está completa.

NaN como resultado de un cálculo aritmético siempre indica que algo ha salido mal en los detalles de la aritmética. Es una manera para que la computadora diga "depuración necesaria aquí". En lugar de encontrar alguna forma de continuar de todos modos con un número que casi nunca es correcto (¿es 0 realmente lo que quieres?), ¿Por qué no encontrar el problema y solucionarlo?

Un problema común en Javascript es que tanto parseInt(...)y parseFloat(...)devolverá NaN si se le da un argumento sin sentido ( null, '', etc.). Solucione el problema en el nivel más bajo posible en lugar de hacerlo en un nivel más alto. Entonces, el resultado del cálculo general tiene una buena probabilidad de tener sentido, y no está sustituyendo un número mágico (0 o 1 o lo que sea) por el resultado de todo el cálculo. (El truco de (parseInt (foo.value) || 0) funciona solo para sumas, no para productos; para los productos que desea que el valor predeterminado sea 1 en lugar de 0, pero no si el valor especificado realmente es 0.)

Tal vez para facilitar la codificación, desea que una función recupere un valor del usuario, lo limpie y proporcione un valor predeterminado si es necesario, como este:

function getFoobarFromUser(elementid) {
        var foobar = parseFloat(document.getElementById(elementid).innerHTML)
        if (isNaN(foobar)) foobar = 3.21;       // default value
        return(foobar.toFixed(2));
}
Chuck Kollars
fuente
2

¿Qué tal una expresión regular ?

function getNum(str) {
  return /[-+]?[0-9]*\.?[0-9]+/.test(str)?parseFloat(str):0;
}

El siguiente código ignorará NaN para permitir el cálculo de números ingresados ​​correctamente

mplungjan
fuente
2

Los métodos que usan isNaN no funcionan si está tratando de usar parseInt, por ejemplo:

parseInt("abc"); // NaN
parseInt(""); // NaN
parseInt("14px"); // 14

Pero en el segundo caso, isNaN produce false (es decir, la cadena nula es un número)

n="abc"; isNaN(n) ? 0 : parseInt(n); // 0
n=""; isNaN(n) ? 0: parseInt(n); // NaN
n="14px"; isNaN(n) ? 0 : parseInt(n); // 14

En resumen, la cadena nula se considera un número válido por isNaN pero no por parseInt. Verificado con Safari, Firefox y Chrome en OSX Mojave.

David Crowe
fuente
1
Una solución obvia es un poco engorrosa, compruebe si hay NaN después de parseInt, no antes: isNaN (parseInt (n))? parseInt (n): 0; // llama a parseInt dos veces :(
David Crowe
1
ese comentario debe ser (el comienzo de) tu respuesta!
Frandroid
Una solución más eficiente supone que la cadena nula es la única anomalía: n == "" || isNaN (n)? 0: parseInt (n); (¿pero qué pasa si hay otras cadenas?)
David Crowe
1
var i = [NaN, 1,2,3];

var j = i.map(i =>{ return isNaN(i) ? 0 : i});

console.log(j)

[0,1,2,3]

KARTHIKEYAN.A
fuente
0

usando la solución de usuario 113716, que por cierto es excelente para evitar todos los demás, si lo he implementado de esta manera para calcular mi cuadro de texto subtotal de la unidad de cuadro de texto y la cantidad de cuadro de texto.

En el proceso de escritura de no números en cuadros de texto de unidad y cantidad, sus valores se reemplazan por cero, por lo que la publicación final de los datos del usuario no tiene números.

     <script src="/common/tools/jquery-1.10.2.js"></script>
     <script src="/common/tools/jquery-ui.js"></script>

     <!----------------- link above 2 lines to your jquery files ------>





    <script type="text/javascript" >
    function calculate_subtotal(){

    $('#quantity').val((+$('#quantity').val() || 0));
    $('#unit').val((+$('#unit').val() || 0));

    var  calculated = $('#quantity').val() * $('#unit').val() ;
    $('#subtotal').val(calculated);


    }
    </script>


      <input type = "text" onChange ="calculate_subtotal();" id = "quantity"/>
      <input type = "text" onChange ="calculate_subtotal();" id = "unit"/>
      <input type = "text" id = "subtotal"/>
webzy
fuente
0

Por favor prueba esta simple función

var NanValue = function (entry) {
    if(entry=="NaN") {
        return 0.00;
    } else {
        return entry;
    }
}
subindas pm
fuente