Converter NaN para 0 em javascript

238

Existe uma maneira de converter valores de NaN para 0 sem uma instrução if:

if (isNaN(a)) a = 0;

É muito chato verificar minhas variáveis ​​todas as vezes.

Tamás Pap
fonte
4
Você não pode simplesmente transformá-lo em uma função?
the_drow 24/09
São apenas 20 caracteres, qual é o problema?
Rusty Fausak
1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }e então apenasnoNaN( a )
Šime Vidas
1
@rfausak Você geralmente não quer se repetir (veja SECO ). Se uma certa funcionalidade é necessária várias vezes, uma função dedicada é preferida.
Šime Vidas

Respostas:

575

Você consegue fazer isso:

a = a || 0

... que converterá um de qualquer valor "falsey" para 0.

Os valores "falsey" são:

  • false
  • null
  • undefined
  • 0
  • "" (cadeia vazia)
  • NaN (Não é um número)

Ou isso, se você preferir:

a = a ? a : 0;

... que terá o mesmo efeito acima.


Se a intenção era testar mais do que apenas NaN, você pode fazer o mesmo, mas faça uma conversão paraNúmero primeiro.

a = +a || 0

Isso usa o operador unário + para tentar converter a em um número. Isso tem o benefício adicional de converter coisas como seqüências numéricas '123'em um número.

A única coisa inesperada pode ser se alguém passa uma matriz que pode ser convertida com êxito em um número:

+['123']  // 123

Aqui temos uma matriz que possui um único membro que é uma sequência numérica. Será convertido com sucesso em um número.

user113716
fonte
A ideia de transformar a verificação em uma função é boa, mas essa é mais elegante.
Tamás Pap
1
@Bakudan: Bom ponto. Eu estava pensando que o OP estava preocupado apenas com o NaNvalor específico . Isso não funcionará como um teste para todos os valores não numéricos. Embora possamos tentar uma conversão de toNumber primeiro. Eu vou atualizar.
User113716
... ah, é por causa do título "Converter NaN para 0" . De qualquer forma, cobriu os dois lados agora.
user113716
2
Obrigado companheiro, selecionei e modifiquei um pouco isso para mim a = a * 1 || 0
Alguém
Impressionante. Graças
APIT John Ismail
32

Usar um til duplo (NÃO bit a bit duplo) - ~~- faz algumas coisas interessantes em JavaScript. Por exemplo, você pode usá-lo em vez de Math.floorou mesmo como uma alternativa ao parseInt("123", 10)! Já foi discutido muito na web, então não vou explicar por que funciona aqui, mas se você estiver interessado: O que é o operador "double til" (~~) em JavaScript?

Podemos explorar essa propriedade de um duplo til para converter NaNem um número e, felizmente, esse número é zero!

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

WickyNilliams
fonte
1
Obrigado, eu não sabia sobre isso ~~em tudo, eu apenas utilizado ao longo do lado com parseFloat()assim: ~~parseFloat($variable);. Muito arrumado :) +1
Rens Tillmann 13/05
23

Escreva seu próprio método e use-o onde quiser um valor numérico:

function getNum(val) {
   if (isNaN(val)) {
     return 0;
   }
   return val;
}
Saket
fonte
1
Se eu passar null, não me dá o resultado esperado de 0. Mais sobre o meu ponto aqui: stackoverflow.com/questions/115548/why-is-isnannull-false-in-js
Andrei Bazanov
2
Além do meu comentário acima, acabei usando, Number(val)pois ele retorna 0quando não consegue descobrir de qualquer maneira.
Andrei Bazanov 15/03
4

Algo mais simples e eficaz para qualquer coisa:

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

... que converterá um de qualquer valor "falsey" para 0.

Os valores "falsey" são:

  • false
  • null
  • undefined
  • 0
  • "" (cadeia vazia)
  • NaN (Não é um número)
Woold
fonte
1
Interessante! Imaginando como ele reage quando val pode ser um valor negativo. Tanto quanto eu testei, não há nada errado com isso, mas por via das dúvidas ...
Luciano
2

Em vez de julgá-lo para que você possa continuar, por que não voltar atrás e se perguntar por que está encontrando um NaN em primeiro lugar?

Se alguma das entradas numéricas de uma operação for NaN, a saída também será NaN. É assim que o padrão atual de ponto flutuante IEEE funciona (não é apenas Javascript). Esse comportamento é por uma boa razão : a intenção subjacente é impedir que você use um resultado falso sem perceber que é falso.

O funcionamento do NaN é que, se algo der errado em alguma sub-sub-sub-operação (produzindo um NaN nesse nível mais baixo), o resultado final também será será NaN, que você reconhecerá imediatamente como um erro, mesmo que seu a lógica de tratamento de erros (talvez jogar / capturar?) ainda não está completa.

NaN como resultado de um cálculo aritmético sempre indica que algo deu errado nos detalhes da aritmética. É uma maneira do computador dizer "é necessário depurar aqui". Em vez de encontrar uma maneira de continuar de qualquer maneira com um número que quase nunca está certo (é 0 realmente o que você quer?), Por que não encontrar o problema e corrigi-lo.

Um problema comum em Javascript é que tanto parseInt(...)e parseFloat(...)retornará NaN se for dado um argumento sem sentido ( null, '', etc). Corrija o problema no nível mais baixo possível e não em um nível superior. Então o resultado do cálculo geral tem uma boa chance de fazer sentido, e você não está substituindo um número mágico (0 ou 1 ou o que for) pelo resultado de todo o cálculo. (O truque de (parseInt (foo.value) || 0) funciona apenas para somas, não produtos - para produtos que você deseja que o valor padrão seja 1 em vez de 0, mas não se o valor especificado realmente for 0.)

Talvez para facilitar a codificação, você queira que uma função recupere um valor do usuário, limpe-o e forneça um valor padrão, se necessário, da seguinte maneira:

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

Que tal um regex ?

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

O código abaixo ignorará o NaN para permitir o cálculo dos números digitados corretamente

mplungjan
fonte
2

Os métodos que usam isNaN não funcionam se você estiver tentando usar parseInt, por exemplo:

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

Mas, no segundo caso, isNaN produz false (ou seja, a string nula é um 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

Em resumo, a cadeia nula é considerada um número válido por isNaN, mas não por parseInt. Verificado com Safari, Firefox e Chrome no OSX Mojave.

David Crowe
fonte
1
Uma solução óbvia é um pouco complicada, verifique NaN após parseInt, não antes: isNaN (parseInt (n))? parseInt (n): 0; // chama parseInt duas vezes :(
David Crowe
1
esse comentário deve ser (o começo de) sua resposta!
frandroid 16/01
Uma solução mais eficiente assume que a cadeia nula é a única anomalia: n == "" || isNaN (n)? 0: parseInt (n); (mas e se houver outras strings?)
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
fonte
0

usando a solução do usuário 113716, que por sinal é ótima para evitar todos aqueles if-else, eu a implementei para calcular minha caixa de texto subtotal da unidade de caixa de texto e da quantidade de caixa de texto.

No processo de gravação de não números em caixas de texto de unidade e quantidade, seus valores são substituídos por zero para que a postagem final dos dados do usuário não possua 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
fonte
0

Por favor, tente esta função simples

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