Como você verifica se um número é NaN em JavaScript?


415

Eu só tentei no console JavaScript do Firefox, mas nenhuma das seguintes afirmações retornam verdadeiras:

parseFloat('geoff') == NaN;

parseFloat('geoff') == Number.NaN;

5
vale a pena ler se o seu objetivo real é verificar números: stackoverflow.com/questions/18082/...
Paul


1
@ Gotico: claro, mas perguntei como verificar se um número é NaN, em oposição a qualquer valor.
Paul D. Waite

3
@ PaulD.Waite Sim, mas muitas pessoas vêm aqui quando pesquisam no Google algo como "como verificar se uma variável é nan em javascript".
Michał Perłakowski

PaulD.Waite Concordo com você, mas tenho a mesma preocupação que @Gothdo. Muitas pessoas abordam essa questão com a intenção de "Como verificar se um valor em JS é NaN". Você pode conferir o comentário de mjohnsonengr na mesma resposta . BTW, eu também sinalizei Esta pergunta para atenção dos moderadores.
Dopeddude

Respostas:


582

Tente este código:

isNaN(parseFloat("geoff"))

Para verificar se algum valor é NaN, em vez de apenas números, veja aqui: Como você testa NaN em Javascript?


8
É necessário o paseFloat?
rahul

23
Se você deseja que uma sequência vazia seja interpretada como NaN, então sim. (Não estou dizendo que você sempre seria.)
Paul D. Waite

1
Se eu fosse você, atribuiria a uma variável e, use a variável de condição! == variável. Como é apresentado nas especificações tc39.github.io/ecma262/#sec-isnan-number
allsyed

3
isNaN(parseFloat("geoff")) // true isNaN(parseFloat("10geo")) // false Como isso é útil?
Prashanth

Isso também pode ser útil para testar w3schools.com/jsref/jsref_isnan.asp
Srijan Chaudhary 14/01

146

Acabei de encontrar essa técnica no livro JavaScript eficaz, que é bem simples:

Como NaN é o único valor JavaScript tratado como desigual para si mesmo, você sempre pode testar se um valor é NaN verificando se há igualdade entre si:

var a = NaN;
a !== a; // true 

var b = "foo";
b !== b; // false 

var c = undefined; 
c !== c; // false

var d = {};
d !== d; // false

var e = { valueOf: "foo" }; 
e !== e; // false

Não percebi isso até @allsyed comentou, mas isso está na especificação da ECMA: https://tc39.github.io/ecma262/#sec-isnan-number


27
Eficaz, mas contra-intuitivo. Eu não gostaria de manter esse tipo de código.
Osa

35
Não é o código que é contra-intuitivo, é NaN.
Jazzy 15/05

20
@ DanM Não é um bug, é o comportamento IEE754 padrão do NaN. É como é implementado nas CPUs e é o comportamento esperado em todas as linguagens de programação do mundo que usam flutuadores.
Tarmil

4
@Tarmil Devidamente observado! Isso é realmente muito interessante; Eu sempre pensei que a estranheza da desigualdade de NaN era uma coisa do Javascript.
M

2
NaN === Nan; // false. Este é um bug conhecido em javascript. isNan é um novo método.
atilkan

52

Use este código:

isNaN('geoff');

Veja os isNaN()documentos no MDN .

alert ( isNaN('abcd'));  // alerts true
alert ( isNaN('2.0'));  // alerts false
alert ( isNaN(2.0));  // alerts false

1
Talvez seja só eu, mas a ideia de NaN fica confusa quando var value = 0/0;e var value2= String("123 131");cria valores de NaN e algo assim var value3 = "abcd";também é um valor de NaN.
22416 Nick Pineda

@NickPineda Por quê?
Sinjai

44

Na medida em que um valor do tipo Number deve ser testado, seja ele NaNou não, a função global isNaNfará o trabalho

isNaN(any-Number);

Para uma abordagem genérica que funciona para todos os tipos em JS, podemos usar qualquer um dos seguintes:

Para usuários do ECMAScript-5:

#1
if(x !== x) {
    console.info('x is NaN.');
}
else {
    console.info('x is NOT a NaN.');
}

Para pessoas que usam o ECMAScript-6:

#2
Number.isNaN(x);

E, para fins de consistência nos dois ECMAScript 5 e 6, também podemos usar esse polyfill para Number.isNan

#3
//Polyfill from MDN
Number.isNaN = Number.isNaN || function(value) {
    return typeof value === "number" && isNaN(value);
}
// Or
Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

por favor, verifique esta resposta para mais detalhes.


6
Obrigado por não apenas usar "isNan ()", mas fornecer uma resposta completamente detalhada. Isso é exatamente o que eu estava procurando quando encontrei essa pergunta no Google.
mjohnsonengr

1
".... estava dando resultados errados para os casos acima" Eu não diria errado, apenas diferente, porque o global isNaNconverte o argumento em um valor numérico primeiro.
Felix Kling

1
@FelixKling Por favor, verifique a resposta atualizada. Obrigado.
dopeddude

1
isNaN ("lorem ipsum"); // true com ES5 estava soprando minha mente
Nick Pineda

2
@NickPineda O sentimento é tão mútuo, mas finalmente o MDN pode explicar dessa maneira "Quando o argumento da função isNaN não é do tipo Number, o valor é primeiro coagido a um Number. O valor resultante é testado para determinar se é NaN. "
dopeddude

16

NaN é um valor especial que não pode ser testado assim. Uma coisa interessante que eu só queria compartilhar é essa

var nanValue = NaN;
if(nanValue !== nanValue) // Returns true!
    alert('nanValue is NaN');

Isso retorna verdadeiro apenas para valores de NaN e é uma maneira segura de testar. Definitivamente deve ser envolvido em uma função ou pelo menos comentado, porque obviamente não faz muito sentido testar se a mesma variável não é igual uma à outra, hehe.


1
Essa não é uma maneira perfeitamente confiável. Conforme as especificações. variável == variável é a maneira mais confiável para verificar se há NaN!
allsyed

1
Veja minha resposta acima neste ^
Jazzy

14

Você deve usar a isNaN(value)chamada de função global , porque:

  • É suportado em vários navegadores
  • Consulte isNaN para documentação

Exemplos:

 isNaN('geoff'); // true
 isNaN('3'); // false

Eu espero que isso te ajude.


1
Sim isNaN('') //falsemas parseInt('') //NaN. O mesmo pode ser dito null.
Silent Penguin


9

Para corrigir o problema em que '1.2geoff'é analisado, basta usar o Number()analisador.

Então, ao invés disso:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

Faça isso:

Number('1.2geoff'); // => NaN
isNaN(Number('1.2geoff')); // => true
isNaN(Number('.2geoff')); // => true
isNaN(Number('geoff')); // => true

Edição: Acabei de notar outro problema com isso embora ... valores falsos (e verdadeiro como um verdadeiro booleano) passaram em Number()retorno como 0! Nesse caso, parseFloat funciona sempre. Então, volte a isso:

function definitelyNaN (val) {
    return isNaN(val && val !== true ? Number(val) : parseFloat(val));
}

E isso cobre aparentemente tudo. Comparei-o em 90% mais lento que o de Lodash, _.isNaNmas esse não cobre todos os NaN:

http://jsperf.com/own-isnan-vs-underscore-lodash-isnan

Só para ficar claro, o meu cuida da interpretação literal humana de algo que é "Não é um Número" e o lodash's cuida da interpretação literal do computador de verificar se algo é "NaN".


7

Embora a resposta de @chiborg esteja correta, há mais coisas a serem observadas:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

A propósito, se você estiver usando esse método para validação de entrada, o resultado será bastante liberal.

Portanto, sim, você pode usar parseFloat(string)(ou no caso de números completos parseInt(string, radix)'e, posteriormente, agrupá-lo com isNaN(), mas esteja ciente da pegadinha com números entrelaçados com caracteres não numéricos adicionais.


1
Interessante. Alguma maneira de combater isso e detectar que "1.2geoff" não é realmente uma sequência de números válida?
Gabe Halsmer

2
Observe que isso acontece apenas quando a sequência começa com um número. parseFloat('test1.2')retornará NaN.
Eduard Luca

6

Solução Simples!

REALMENTE super simples! Aqui! Tenha esse método!

function isReallyNaN(a) { return a !== a; };

Use tão simples quanto:

if (!isReallyNaN(value)) { return doingStuff; }

Veja o teste de desempenhohere usando esta função vsselected answer

Além disso: Veja abaixo o 1º exemplo para algumas implementações alternativas.


Exemplo:

function isReallyNaN(a) { return a !== a; };

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('$5.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': [],
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined
  }

for (x in example) {
    var answer = isReallyNaN(example[x]),
        strAnswer = answer.toString();
    $("table").append($("<tr />", { "class": strAnswer }).append($("<th />", {
        html: x
    }), $("<td />", {
        html: strAnswer
    })))
};
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table></table>

Existem alguns caminhos alternativos para a implementação, se você não quiser usar um método com nome alternativo e desejar garantir que ele esteja disponível globalmente. Aviso Essas soluções envolvem a alteração de objetos nativos e podem não ser a melhor solução. Sempre tenha cuidado e esteja ciente de que outras bibliotecas que você pode usar podem depender do código nativo ou de alterações semelhantes.

Implementação alternativa 1: Substitua o isNaNmétodo nativo .

//  Extremely simple. Just simply write the method.
window.isNaN = function(a) { return a !==a; }

Implementação alternativa 2: anexar ao objeto de número
* Sugerido, pois também é um preenchimento múltiplo para ECMA 5 a 6

Number['isNaN'] || (Number.isNaN = function(a) { return a !== a });
//  Use as simple as
Number.isNaN(NaN)

Teste de solução alternativa se vazio

Um método simples de janela que escrevi para testar se o objeto está vazio . É um pouco diferente, pois não indica se o item é "exatamente" NaN , mas imaginei que iria vomitar isso, pois também pode ser útil ao procurar itens vazios.

/** isEmpty(varried)
 *  Simple method for testing if item is "empty"
 **/
;(function() {
   function isEmpty(a) { return (!a || 0 >= a) || ("object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a))); };
   window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();

Exemplo:


Verificação extremamente profunda se estiver vazia

Este último é um pouco profundo, até verificando se um Objeto está cheio de Objetos em branco. Tenho certeza de que há espaço para melhorias e possíveis poços, mas até agora parece que ele captura quase tudo.


1
@ PaulD.Waite talvez seja este aplicativo, mas não vejo uma resposta aceita. Na verdade, eu só vejo cerca de 5 respostas, mas eu vejo isso diz que existem 15
SpYk3HH

1
Qual aplicativo você está usando?
Paul D. Waite

2
@ PaulD.Waite O SE one para android. na galáxia s3
SpYk3HH

1
Aha. Eu não tenho o aplicativo para me olhar, mas aqui está um link para a resposta aceita: stackoverflow.com/a/2652335/20578
Paul D. Waite

@ PaulD.Waite Ah, entendo. Suponho que, em resposta direta apenas à pergunta em si mesma, essa resposta possa ser suficiente. Postei minha resposta em outra pergunta em relação total "JS maneira de verificar se é 'realmente' NaN", uma vez que isNaNNÃO é confiável. Fui comentado lá e disse que essa pergunta se adequaria melhor à minha resposta, movendo-a para aqui. Basta colocar algo útil / útil em relação a esse problema que aparecerá na pesquisa do Google em questão is it NaN?,. Na nota lateral, minha resposta seria mais precisa com mais frequência do que a resposta selecionada.
SpYk3HH

5

Eu só quero compartilhar outra alternativa, não é necessariamente melhor do que outras aqui, mas acho que vale a pena olhar:

function customIsNaN(x) { return (typeof x == 'number' && x != 0 && !x); }

A lógica por trás disso é que todos os números, exceto 0e NaNlançados paratrue .

Fiz um teste rápido e funciona tão bem quanto Number.isNaN e verificando se é falso. Todos os três têm melhor desempenho do queisNan

Os resultados

customIsNaN(NaN);            // true
customIsNaN(0/0);            // true
customIsNaN(+new Date('?')); // true

customIsNaN(0);          // false
customIsNaN(false);      // false
customIsNaN(null);       // false
customIsNaN(undefined);  // false
customIsNaN({});         // false
customIsNaN('');         // false

Pode se tornar útil se você quiser evitar a isNaNfunção interrompida .


5

Se seu ambiente suportar o ECMAScript 2015 , convém usar Number.isNaNpara garantir que o valor seja realmenteNaN .

O problema isNaNé que, se você usar isso com dados não numéricos, existem poucas regras confusas (conforme o MDN). Por exemplo,

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

Portanto, em ambientes suportados pelo ECMA Script 2015, convém usar

Number.isNaN(parseFloat('geoff'))

7
Meu ambiente suporta apenas o ECMAScript XP Home Edition :(
Paul D. Waite

1
@ PaulD.Waite (espero que significava IE 6: D) Não há problema :-) Basta lembrar que isNaNpoderia colocar você em problemas e lembre-se de usar Number.isNaNem ECMAScript 2015 ambientes :-)
thefourtheye

5

NaN em JavaScript significa "Não é um número", embora seu tipo seja realmente número.

typeof(NaN) // "number"

Para verificar se uma variável tem o valor NaN, não podemos simplesmente usar a função isNaN (), porque isNaN () tem o seguinte problema, veja abaixo:

var myVar = "A";
isNaN(myVar) // true, although "A" is not really of value NaN

O que realmente acontece aqui é que myVar é implicitamente coagido a um número:

var myVar = "A";
isNaN(Number(myVar)) // true. Number(myVar) is NaN here in fact

Na verdade, faz sentido, porque "A" na verdade não é um número. Mas o que realmente queremos verificar é se myVar tem exatamente o valor NaN.

Então isNaN () não pode ajudar. Então, o que devemos fazer?

Tendo em conta que NaN é o único valor JavaScript que é tratado de forma desigual, podemos verificar sua igualdade usando: ==

var myVar; // undefined
myVar !== myVar // false

var myVar = "A";
myVar !== myVar // false

var myVar = NaN
myVar !== myVar // true

Então, para concluir , se é verdade que uma variável! == em si, então essa variável é exatamente do valor NaN:

function isOfValueNaN(v) {
    return v !== v;
}

var myVar = "A";
isNaN(myVar); // true
isOfValueNaN(myVar); // false

4

Eu uso aisNaN função de sublinhado porque em JavaScript:

isNaN(undefined) 
-> true

Pelo menos, esteja ciente disso.


10
Estou confuso. Por que o retorno de isNaN true quando passado undefinedé um comportamento incorreto? É verdade que undefinednão é um número, não é?
Xaxis

3
O @Xaxis NaN não deve ser considerado equivalente a indefinido, pois ambos são valores especiais com significados específicos e diferentes . Considere o seguinte: eu tenho um valor, mas não estou dizendo o que é, talvez seja um número e talvez não seja, no entanto, do seu ponto de vista, é indefinido.
Corin

1
@Corin undefinedpode ser diferente algo que NaN, no entanto, ainda não é um número tão isNaN(undefined)deve ser (e é)true
Neuhaus

4

Talvez também isso:

function isNaNCustom(value){
    return value.toString() === 'NaN' && 
           typeof value !== 'string' && 
           typeof value === 'number'
}

3

Parece que isNaN () não é suportado no Node.js imediatamente.
Eu trabalhei com

var value = 1;
if (parseFloat(stringValue)+"" !== "NaN") value = parseFloat(stringValue);

Claro, mas eu não estava perguntando sobre o Node.js.
Paul D. Waite



2

A regra é:

NaN != NaN

O problema da função isNaN () é que ela pode retornar resultados inesperados em alguns casos:

isNaN('Hello')      //true
isNaN('2005/12/12') //true
isNaN(undefined)    //true
isNaN('NaN')        //true
isNaN(NaN)          //true
isNaN(0 / 0)        //true

Uma maneira melhor de verificar se o valor é realmente NaN é:

function is_nan(value) {
    return value != value
}

is_nan(parseFloat("geoff"))

1

De acordo com a IEEE 754, todas as relações envolvendo NaN são avaliadas como falsas, exceto! =. Assim, por exemplo, (A> = B) = falso e (A <= B) = falso se A ou B ou ambos são / são NaN.


1

Escrevi esta resposta para outra pergunta no StackOverflow, onde outra verifica quando, NaN == nullmas depois foi marcada como duplicada, para não desperdiçar meu trabalho.

Veja a Mozilla Developer Network sobre NaN.


Resposta curta

Basta usar distance || 0quando quiser ter certeza de que o valor é um número adequado ou isNaN()verificar.

Resposta longa

O NaN (não é um número) é um objeto global esquisito em javascript frequentemente retornado quando alguma operação matemática falha.

Você queria verificar se NaN == nullquais resultados false. Mais NaN == NaNresultados ainda comfalse .

Uma maneira simples de descobrir se a variável é NaNé uma função globalisNaN() .

Outro é x !== x que só é verdadeiro quando x é NaN. (obrigado por lembrar a @ raphael-schweikert)

Mas por que a resposta curta funcionou?

Vamos descobrir.

Quando você chama NaN == falseo resultado é o falsemesmo com NaN == true.

Em algum lugar nas especificações, o JavaScript tem um registro com valores sempre falsos, que inclui:

  • NaN - Não é um número
  • "" - string vazia
  • false - um falso booleano
  • null - objeto nulo
  • undefined - variáveis ​​indefinidas
  • 0 - 0 numérico, incluindo +0 e -0

1
“A única maneira simples de descobrir se a variável é NaN é uma função global isNaN ()” - não é verdade; existe outra maneira simples: var xIsNaN = x !== x;isso só é verdadeiro se x for NaN.
Raphael Schweikert

1

Outra solução é mencionada na página parseFloat do MDN

Ele fornece uma função de filtro para fazer uma análise rigorosa

var filterFloat = function (value) {
    if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/
      .test(value))
      return Number(value);
  return NaN;
}


console.log(filterFloat('421'));               // 421
console.log(filterFloat('-421'));              // -421
console.log(filterFloat('+421'));              // 421
console.log(filterFloat('Infinity'));          // Infinity
console.log(filterFloat('1.61803398875'));     // 1.61803398875
console.log(filterFloat('421e+0'));            // NaN
console.log(filterFloat('421hop'));            // NaN
console.log(filterFloat('hop1.61803398875'));  // NaN

E então você pode usar isNaNpara verificar se éNaN


1

A maneira exata de verificar é:

//takes care of boolen, undefined and empty

isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'

1

Eu criei essa pequena função que funciona como um encanto. Em vez de procurar por NaN, que parece ser contra-intuitivo, você verifica um número. Tenho certeza de que não sou o primeiro a fazê-lo dessa maneira, mas pensei em compartilhar.

function isNum(val){
    var absVal = Math.abs(val);
    var retval = false;
    if((absVal-absVal) == 0){
        retval = true
    }

    return retval;
}

1

Encontrado de outra maneira, apenas por diversão.

function IsActuallyNaN(obj) {
  return [obj].includes(NaN);  
}

1

A resposta de marksyzm funciona bem, mas não retorna falso, Infinitypois o Infinito não é tecnicamente um número.

Eu vim com uma isNumberfunção que irá verificar se é um número.

function isNumber(i) {
    return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY].indexOf(i) === -1;
}

console.log(isNumber(Infinity));
console.log(isNumber("asdf"));
console.log(isNumber(1.4));
console.log(isNumber(NaN));
console.log(isNumber(Number.MAX_VALUE));
console.log(isNumber("1.68"));

UPDATE: notei que esse código falha em alguns parâmetros, por isso o melhorei.

function isNumber(i) {//function for checking if parameter is number
if(!arguments.length) {
throw new SyntaxError("not enough arguments.");
	} else if(arguments.length > 1) {
throw new SyntaxError("too many arguments.");
	} else if([Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY].indexOf(i) !== -1) {
throw new RangeError("number cannot be \xB1infinity.");
	} else if(typeof i === "object" && !(i instanceof RegExp) && !(i instanceof Number) && !(i === null)) {
throw new TypeError("parameter cannot be object/array.");
	} else if(i instanceof RegExp) {
throw new TypeError("parameter cannot be RegExp.");
	} else if(i == null || i === undefined) {
throw new ReferenceError("parameter is null or undefined.");
	} else {
return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && (i === i);
	}
}
console.log(isNumber(Infinity));
console.log(isNumber(this));
console.log(isNumber(/./ig));
console.log(isNumber(null));


Sua premissa de que o infinito não é tecnicamente um número é tecnicamente defeituosa: math.stackexchange.com/questions/36289/is-infinity-a-number . Da minha leitura das respostas é que o infinito ser um número depende do contexto.
Jon P

eu estou indo para mover esta a outra pergunta
adddff

1
alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1);

Isso não é elegante. mas depois de tentar isNAN () cheguei a esta solução, que é outra alternativa. Neste exemplo, eu também permiti '.' porque eu estou mascarando para flutuar. Você também pode reverter isso para garantir que nenhum número seja usado.

("1234567890".indexOf(String.fromCharCode(mycharacter))==-1)

Essa é uma avaliação de caractere único, mas você também pode fazer um loop através de uma sequência para verificar se há números.


1

Você pode verificar o NaN usando a função javascript isNaN. Apenas passando o número ou valor para a função isNaN

isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true

0

Basta converter o resultado em String e comparar com 'NaN'.

var val = Number("test");
if(String(val) === 'NaN') {
   console.log("true");
}

0

É (NaN> = 0) ? ...... " Eu não sei ".

function IsNotNumber( i ){
    if( i >= 0 ){ return false; }
    if( i <= 0 ){ return false; }
    return true;
}

As condições são executadas apenas se TRUE .

Não em FALSO .

Não em " Eu não sei ".


não é muito útil se você explicitamente procurar valores NaN istead de olhar para a frente
liviu blidar
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.