¿Cómo verificas que un número es NaN en JavaScript?


415

Solo lo he estado probando en la consola JavaScript de Firefox, pero ninguna de las siguientes afirmaciones es verdadera:

parseFloat('geoff') == NaN;

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

55
vale la pena leer si su objetivo real es verificar los números: stackoverflow.com/questions/18082/…
Paul


1
@Gothdo: claro, pero pregunté cómo verificar que un número sea ​​NaN, en lugar de cualquier valor.
Paul D. Waite

3
@ PaulD.Waite Sí, pero mucha gente viene aquí cuando busca en Google algo así como "cómo verificar si una variable es nan en javascript".
Michał Perłakowski

PaulD.Waite Estoy de acuerdo con usted, pero tengo la misma preocupación que @Gothdo. Muchas personas llegan a esta pregunta con la intención de "Cómo verificar si un valor en JS es NaN". Puedes consultar el comentario de mjohnsonengr en la misma respuesta . Por cierto, yo también he marcado esta pregunta para la atención de los moderadores.
dopeddude

Respuestas:


582

Prueba este código:

isNaN(parseFloat("geoff"))

Para verificar si algún valor es NaN, en lugar de solo números, consulte aquí: ¿Cómo se prueba para NaN en Javascript?


8
¿Hay necesidad de paseFloat?
rahul

23
Si desea que se interprete una cadena vacía NaN, entonces sí. (No digo que siempre lo harías)
Paul D. Waite

1
Si fuera usted, lo asignaría a una variable y, ¡usaría la variable de condición! == variable. Como se presenta en las especificaciones tc39.github.io/ecma262/#sec-isnan-number
allsyed

3
isNaN(parseFloat("geoff")) // true isNaN(parseFloat("10geo")) // false ¿Cómo es esto útil?
Prashanth

Esto también podría ser útil para probar w3schools.com/jsref/jsref_isnan.asp
Srijan Chaudhary

146

Acabo de encontrar esta técnica en el libro JavaScript eficaz que es bastante simple:

Dado que NaN es el único valor de JavaScript que se trata como desigual a sí mismo, siempre puede probar si un valor es NaN verificándolo para que sea igual a sí mismo:

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

No me di cuenta de esto hasta que @allsyed comentó, pero esto está en la especificación de ECMA: https://tc39.github.io/ecma262/#sec-isnan-number


27
Eficaz pero contradictorio. No me gustaría mantener este tipo de código.
osa

35
No es el código contradictorio, es NaN.
Jazzy

20
@DanM No es un error, es el comportamiento estándar IEE754 de NaN. Es cómo se implementa en las CPU, y es el comportamiento esperado en cada lenguaje de programación en el mundo el que usa flotantes.
Tarmil

44
@Tarmil ¡Debidamente notado! Eso es realmente muy interesante; Siempre pensé que la rareza de la desigualdad de NaN era cosa de Javascript.
Dan M

2
NaN === Nan; // falso. Este es un error conocido en JavaScript. isNan es un nuevo método.
atilkan

52

Usa este código:

isNaN('geoff');

Ver isNaN()documentos en MDN .

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

1
Tal vez soy solo yo, pero la idea de NaN se vuelve confusa cuando var value = 0/0;y var value2= String("123 131");crea valores de NaN y algo como esto var value3 = "abcd";también es un valor de NaN.
Nick Pineda

@NickPineda ¿Por qué?
Sinjai

44

Siempre que se pruebe un valor de tipo Número , sea NaNo no, la función global isNaNhará el trabajo

isNaN(any-Number);

Para un enfoque genérico que funcione para todos los tipos en JS, podemos usar cualquiera de los siguientes:

Para usuarios de ECMAScript-5:

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

Para personas que usan ECMAScript-6:

#2
Number.isNaN(x);

Y para propósitos de consistencia en ECMAScript 5 y 6, también podemos usar este 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 revise esta respuesta para más detalles.


66
Gracias por no solo usar "isNan ()" sino por proporcionar una respuesta completamente detallada. Esto es EXACTAMENTE lo que estaba buscando cuando encontré esta pregunta en Google.
mjohnsonengr

1
".... estaba dando resultados incorrectos para los casos anteriores" No diría incorrecto, simplemente diferente, porque el global isNaNconvierte primero el argumento a un valor numérico.
Felix Kling

1
@FelixKling Por favor verifique la respuesta actualizada. Gracias.
dopeddude

1
isNaN ("lorem ipsum"); // cierto con ES5 me estaba volviendo loco
Nick Pineda

2
@NickPineda El sentimiento es muy mutuo, pero finalmente MDN podría explicarlo de esta manera "Cuando el argumento de la función isNaN no es del tipo Número, el valor primero se convierte en un Número. El valor resultante se prueba para determinar si es Yaya."
dopeddude

16

NaN es un valor especial que no se puede probar así. Una cosa interesante que solo quería compartir es esto

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

Esto devuelve verdadero solo para los valores de NaN y es una forma segura de prueba. Definitivamente debería estar envuelto en una función o al menos comentado, porque obviamente no tiene mucho sentido probar si la misma variable no es igual entre sí, jeje.


1
Esa no es una forma perfectamente confiable. Según las especificaciones. variable! == variable es la forma más confiable de verificar NaN
allsyed

1
Vea mi respuesta anterior sobre esto ^
Jazzy

14

Debe usar la isNaN(value)llamada a la función global , porque:

  • Es compatible con navegador cruzado
  • Ver isNaN para documentación

Ejemplos:

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

Espero que esto ayude.


1
Si isNaN('') //falsepero parseInt('') //NaN. Lo mismo puede decirse de null.
Silent Penguin

13

A partir de ES6 , Object.is(..)es una nueva utilidad que se puede utilizar para probar dos valores de igualdad absoluta:

var a = 3 / 'bar';
Object.is(a, NaN); // true


9

Para solucionar el problema donde '1.2geoff'se analiza, solo usa el Number()analizador.

Entonces, en lugar de esto:

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

Hacer esto:

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

EDITAR: acabo de notar otro problema de esto ... los valores falsos (y verdadero como un booleano real) se Number()devolvieron como 0! En cuyo caso ... parseFloat funciona siempre en su lugar. Entonces volvamos a eso:

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

Y eso cubre aparentemente todo. Lo comparé en un 90% más lento que el de Lodash, _.isNaNpero ese no cubre todos los NaN:

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

Para ser claros, el mío se encarga de la interpretación literal humana de algo que no es "un número" y lodash se encarga de la interpretación literal de la computadora para verificar si algo es "NaN".


7

Si bien la respuesta de @chiborg ES correcta, hay más que debe tenerse en cuenta:

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

El punto es, si está utilizando este método para la validación de la entrada, el resultado será bastante liberal.

Entonces, sí, puede usar parseFloat(string)(o en el caso de números completos parseInt(string, radix)'y luego envolverlo con eso isNaN(), pero tenga en cuenta el gotcha con números entrelazados con caracteres no numéricos adicionales.


1
Interesante. ¿Alguna forma de contrarrestar esto y detectar que "1.2geoff" no es realmente una cadena de números válida?
Gabe Halsmer el

2
Tenga en cuenta que esto sucede solo cuando la cadena comienza con un número. parseFloat('test1.2')devolverá NaN.
Eduard Luca

6

¡Solución simple!

REALMENTE super simple! ¡Aquí! ¡Ten este método!

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

Use tan simple como:

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

Vea la prueba de rendimientohere usando esta función vsselected answer

Además: vea a continuación el primer ejemplo para un par de implementaciones alternativas.


Ejemplo:

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>

Hay un par de caminos alternativos que debe seguir para la implementación, si no desea utilizar un método con un nombre alternativo y desea asegurarse de que esté más disponible a nivel mundial. Advertencia Estas soluciones implican la alteración de objetos nativos y pueden no ser su mejor solución. Siempre tenga cuidado y tenga en cuenta que otras bibliotecas que pueda utilizar pueden depender de código nativo o alteraciones similares.

Implementación alternativa 1: Reemplazar isNaNmétodo nativo .

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

Implementación alternativa 2: anexar al objeto de número
* Sugerido, ya que también es un relleno de polietileno para ECMA 5 a 6

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

Prueba de solución alternativa si está vacía

Un método de ventana simple escribí esa prueba si el objeto está vacío . Es un poco diferente en el sentido de que no da si el artículo es "exactamente" NaN , pero pensé que arrojaría esto, ya que también puede ser útil al buscar artículos vacíos.

/** 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);
})();

Ejemplo:


Verificación extremadamente profunda si está vacío

Este último va un poco profundo, incluso comprobando si un Objeto está lleno de Objetos en blanco. Estoy seguro de que tiene margen de mejora y posibles pozos, pero hasta ahora, parece capturar casi todo.


1
@ PaulD.Waite quizás sea esta aplicación, pero no veo una respuesta aceptada. De hecho, solo veo alrededor de 5 respuestas, pero veo que dice que hay 15
SpYk3HH

1
¿Qué aplicación estás usando?
Paul D. Waite

2
@ PaulD.Waite El SE para Android. en galaxy s3
SpYk3HH

1
Ajá. No tengo la aplicación para mirarme, pero aquí hay un enlace a la respuesta aceptada: stackoverflow.com/a/2652335/20578
Paul D. Waite

@ PaulD.Waite Ah, ya veo. Supongo que, en respuesta directa solo a la pregunta en sí misma, esa respuesta puede ser suficiente. Publiqué mi respuesta en otra pregunta en relación total con "JS manera de verificar si es 'realmente' NaN", ya isNaNque NO es confiable. Me comentaron allí y me dijeron que esta pregunta se adaptaría mejor a mi respuesta, moviéndola aquí. Simplemente poner algo útil / útil por ahí en relación con este tema que aparecerá en una búsqueda en Google del tema en cuestión, is it NaN?. Como nota al margen, mi respuesta sería más precisa con más frecuencia que la respuesta seleccionada.
SpYk3HH

5

Solo quiero compartir otra alternativa, no es necesariamente mejor que otras aquí, pero creo que vale la pena mirar:

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

La lógica detrás de esto es que todos los números excepto 0y NaNson emitidos atrue .

He hecho una prueba rápida y funciona tan bien como Number.isNaN para comprobar si es falso. Los tres funcionan mejor queisNan

Los 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

Puede ser útil si desea evitar la isNaNfunción rota .


5

Si su entorno es compatible con ECMAScript 2015 , puede utilizarlo Number.isNaNpara asegurarse de que el valor sea realmenteNaN .

El problema isNaNes que si usa eso con datos no numéricos hay pocas reglas confusas (según MDN). Por ejemplo,

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

Por lo tanto, en los entornos compatibles con ECMA Script 2015, es posible que desee utilizar

Number.isNaN(parseFloat('geoff'))

77
Mi entorno solo es compatible con ECMAScript XP Home Edition :(
Paul D. Waite

1
@ PaulD.Waite (espero que haya querido decir IE 6: D) No hay problema :-) Solo recuerde que isNaNpodría meterlo en problemas y recuerde usarlo Number.isNaNen entornos ECMAScript 2015 :-)
thefourtheye

5

NaN en JavaScript significa "No es un número", aunque su tipo es en realidad número.

typeof(NaN) // "number"

Para verificar si una variable es de valor NaN, no podemos simplemente usar la función isNaN (), porque isNaN () tiene el siguiente problema, ver a continuación:

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

Lo que realmente sucede aquí es que myVar se coacciona implícitamente a un número:

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

En realidad tiene sentido, porque "A" en realidad no es un número. Pero lo que realmente queremos comprobar es si myVar es exactamente de valor NaN.

Entonces isNaN () no puede ayudar. Entonces, ¿qué debemos hacer en su lugar?

A la luz de que NaN es el único valor de JavaScript que se trata de manera desigual, por lo que podemos verificar su igualdad usando! ==

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

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

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

Para concluir , si es cierto que una variable! == en sí misma, entonces esta variable es exactamente de valor NaN:

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

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

4

Uso laisNaN función de subrayado porque en JavaScript:

isNaN(undefined) 
-> true

Por lo menos, ten en cuenta ese problema.


10
Estoy confundido. ¿Por qué isNaN devuelve verdadero cuando se pasa undefinedsería un comportamiento incorrecto? Es cierto que undefinedno es un número, ¿no es así?
Xaxis

3
@Xaxis NaN no debe considerarse equivalente a indefinido, ambos son valores especiales con significados específicos y diferentes . Considere esto: tengo un valor, pero no estoy diciendo qué es, tal vez sea un número y tal vez no lo sea, sin embargo, desde su punto de vista, no está definido.
Corin

1
@Corin undefinedpuede ser algo diferente de NaN, sin embargo, todavía no es un número, por lo que isNaN(undefined)debería ser (y lo es)true
neuhaus

4

Quizás también esto:

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

3

Parece que isNaN () no es compatible con Node.js fuera de la caja.
Trabajé con

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

Claro, pero no estaba preguntando sobre Node.js.
Paul D. Waite



2

La regla es:

NaN != NaN

El problema de la función isNaN () es que puede devolver resultados inesperados en algunos casos:

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

Una mejor manera de verificar si el valor es realmente NaN es:

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

is_nan(parseFloat("geoff"))

1

De acuerdo con IEEE 754, todas las relaciones que involucran NaN se evalúan como falsas, excepto! =. Así, por ejemplo, (A> = B) = falso y (A <= B) = falso si A o B o ambos son / son NaN.


1

Escribí esta respuesta a otra pregunta en StackOverflow donde otro comprueba cuándo, NaN == nullpero luego se marcó como duplicado, por lo que no quiero desperdiciar mi trabajo.

Mire acerca de la red de desarrolladores de MozillaNaN .


Respuesta corta

Solo úselo distance || 0cuando quiera asegurarse de que el valor sea un número apropiado o isNaN()para verificarlo.

Respuesta larga

El NaN (Not-a-Number) es un Objeto global extraño en JavaScript que se devuelve con frecuencia cuando falla alguna operación matemática.

Querías comprobar si NaN == nullresulta false. Hovewer incluso NaN == NaNresulta confalse .

Una manera simple de averiguar si la variable NaNes una función globalisNaN() .

Otro es x !== x que solo es cierto cuando x es NaN. (gracias por recordar a @ raphael-schweikert)

Pero, ¿por qué funcionó la respuesta corta?

Vamos a averiguar.

Cuando llamas NaN == falseal resultado es false, lo mismo con NaN == true.

En algún lugar de las especificaciones, JavaScript tiene un registro con valores siempre falsos, que incluye:

  • NaN - No un número
  • "" - cuerda vacía
  • false - un falso booleano
  • null - objeto nulo
  • undefined - variables indefinidas
  • 0 - 0 numérico, que incluye +0 y -0

1
"La única forma simple de averiguar si la variable es NaN es una función global isNaN ()" - no es cierto; Hay otra manera simple: var xIsNaN = x !== x;esto es cierto solo si x es NaN.
Raphael Schweikert

1

Se menciona otra solución en la página parseFloat de MDN

Proporciona una función de filtro para realizar un análisis estricto.

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

Y luego puedes usar isNaNpara verificar si esNaN


1

La forma exacta de verificar es:

//takes care of boolen, undefined and empty

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

1

He creado esta pequeña función que funciona a las mil maravillas. En lugar de buscar NaN, que parece ser contrario a la intuición, verifica un número. Estoy bastante seguro de que no soy el primero en hacerlo de esta manera, pero pensé en compartirlo.

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

    return retval;
}

1

Encontré otra forma, solo por diversión.

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

1

La respuesta de marksyzm funciona bien, pero no devuelve falso Infinityya que Infinity técnicamente no es un número.

Se me ocurrió una isNumberfunción que verificará si es un 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"));

ACTUALIZACIÓN: noté que este código falla para algunos parámetros, así que lo mejoré.

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));


Su premisa de que el infinito técnicamente no es un número tiene fallas técnicas: math.stackexchange.com/questions/36289/is-infinity-a-number . Según mi lectura de las respuestas, el hecho de que el número sea infinito depende del contexto.
Jon P

voy a pasar esto a otra pregunta
adddff

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

Esto no es elegante. pero después de probar isNAN () llegué a esta solución, que es otra alternativa. En este ejemplo también permití '.' porque estoy enmascarando para flotar. También puede revertir esto para asegurarse de que no se usen números.

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

Esta es una evaluación de un solo carácter, pero también puede recorrer una cadena para verificar cualquier número.


1

Puede verificar NaN usando la función isNaN javascript. Simplemente pasando el número o valor a la función 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

Simplemente convierta el resultado a String y compárelo con 'NaN'.

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

0

¿Es (NaN> = 0) ? ...... " No sé ".

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

Las condiciones solo se ejecutan si es VERDADERO .

No en FALSO .

No en " No lo sé ".


no es muy útil si buscas explícitamente valores de NaN en lugar de buscar lo contrario
liviu blidar
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.