Este código en JS me da una ventana emergente que dice "Creo que nulo es un número", lo que me parece un poco inquietante. ¿Qué me estoy perdiendo?
if (isNaN(null)) {
alert("null is not a number");
} else {
alert("i think null is a number");
}
Estoy usando Firefox 3. ¿Es eso un error del navegador?
Otras pruebas:
console.log(null == NaN); // false
console.log(isNaN("text")); // true
console.log(NaN == "text"); // false
Entonces, ¿el problema parece no ser una comparación exacta con NaN?
Editar: Ahora que la pregunta ha sido respondida, he limpiado mi publicación para tener una mejor versión para el archivo. Sin embargo, esto hace que algunos comentarios e incluso algunas respuestas sean un poco incomprensibles. No culpes a sus autores. Entre las cosas que cambié fue:
- Se eliminó una nota que decía que había arruinado el titular en primer lugar al revertir su significado
- Las respuestas anteriores mostraron que no dije con suficiente claridad por qué pensaba que el comportamiento era extraño, así que agregué los ejemplos que verifican una cadena y hacen una comparación manual.
javascript
Hanno Fietz
fuente
fuente

Respuestas:
Creo que el código está tratando de preguntar, "¿es
xnumérico?" con el caso específico aquí dex = null. La funciónisNaN()se puede usar para responder esta pregunta, pero semánticamente se refiere específicamente al valorNaN. De Wikipedia paraNaN:En la mayoría de los casos, pensamos que la respuesta a "¿es numérico nulo?" debería ser no. Sin embargo,
isNaN(null) == falsees semánticamente correcto, porquenullno lo esNaN.Aquí está la explicación algorítmica:
La función
isNaN(x)intenta convertir el parámetro pasado a un número 1 (equivalente aNumber(x)) y luego prueba si el valor esNaN. Si el parámetro no se puede convertir a un número,Number(x)devolveráNaN2 . Por lo tanto, si la conversión del parámetroxa un número resultaNaN, devuelve verdadero; de lo contrario, devuelve falso.Entonces, en el caso específico
x = null,nullse convierte al número 0, (intente evaluarNumber(null)y ver que devuelve 0,) yisNaN(0)devuelve falso. Una cadena que solo tiene dígitos puede convertirse en un número e isNaN también devuelve falso. Una cadena (p'abcd'. Ej. ) Que no se puede convertir a un número haráisNaN('abcd')que devuelva verdadero, específicamente porqueNumber('abcd')devuelveNaN.Además de estos casos extremos aparentes, hay razones numéricas estándar para devolver NaN como 0/0.
En cuanto a las pruebas de igualdad aparentemente inconsistentes que se muestran en la pregunta, el comportamiento de
NaNse especifica de modo que cualquier comparaciónx == NaNsea falsa, independientemente del otro operando, incluido élNaNmismo 1 .fuente
NaN !== NaN. Entonces, creo que no es totalmente correcto decirloNumber('abcd') == NaNporqueNumber('abcd')esNaNpero no igual aNaN. Adoro JavaScript.Number('abcd')esNaN, pero he dado a entender que prueba verdadera de la igualdad, que no es el caso. Lo editaréisNaNy estánNumberdiseñados para comportarse de esa manera.nulla0solo (al menos en este contexto) ocurre dentro de laisNaN()función, que coacciona su argumento.Me encontré con este problema yo mismo.
Para mí, la mejor manera de usar isNaN es así
isNaN(parseInt(myInt))tomando el ejemplo de phyzome de arriba,
(Alineé el resultado de acuerdo con la entrada, espero que sea más fácil de leer).
Esto me parece mejor.
fuente
myInt= "123d".parseIntconvierte "123d" a 123, que luego falla laisNaNprueba.isNaN(parseInt(str,10)) || isNaN(Number()). por cierto, para mí, ya que tengo que ejecutarparseIntpara usar el valor numérico de la cadena, lo que permite que "123d" sea considerado como un número válido está bien. Sin embargo, veo la necesidad de detectar ese escenario también.(Mi otro comentario tiene un enfoque práctico. Aquí está el lado teórico).
Busqué el estándar ECMA 262 , que es lo que implementa Javascript. Su especificación para isNan:
La sección 9.3 especifica el comportamiento de
ToNumber(que no es una función invocable, sino un componente del sistema de conversión de tipos). Para resumir la tabla, ciertos tipos de entrada pueden producir un NaN. Estos son tipoundefined, tiponumber(pero solo el valorNaN), cualquier objeto cuya representación primitiva seaNaN, y cualquier objetostringque no pueda analizarse. Este hojasundefined,NaN,new Number(NaN), y la mayoría de las cadenas.Cualquier entrada de este tipo que se produzca
NaNcomo salida cuando se pase aToNumberproducirá untruecuando se alimente aisNaN. Comonullpuede convertirse con éxito en un número, no producetrue.Y es por eso.
fuente
Esto es realmente inquietante. Aquí hay una serie de valores que probé:
Evalúa (en la consola Firebug) para:
Cuando llamo
x.map(isNaN)(para llamar a isNaN en cada valor), obtengo:En conclusión, ¡
isNaNparece bastante inútil! ( Editar : excepto que resulta que isNaN solo se define sobre Number, en cuyo caso funciona bien, solo con un nombre engañoso).Por cierto, aquí están los tipos de esos valores:
fuente
Nulo no es NaN, así como una cadena no es NaN. isNaN () solo prueba si realmente tienes el objeto NaN.
fuente
No estoy exactamente seguro cuando se trata de JS, pero he visto cosas similares en otros idiomas y generalmente es porque la función solo está verificando si nulo es exactamente igual a NaN (es decir, nulo === NaN sería falso). En otras palabras, no es que piense que nulo es de hecho un número, sino que nulo no es NaN. Esto se debe probablemente a que ambos están representados de manera diferente en JS para que no sean exactamente iguales, de la misma manera que 9! == '9'.
fuente
En ES5, se define como
isNaN (number)devuelve verdadero si el argumento coacciona a NaN, y de lo contrario devuelve falso.Y vea la tabla de conversión La operación abstracta ToNumber . Entonces, internamente, la evaluación del motor js
ToNumber(Null)es+0, luego eventualmenteisNaN(null)esfalsefuente
Nota:
El operador == realiza conversión de tipo, mientras que === no.
El sitio web de Douglas Crockford , un Yahoo! Evangelista de JavaScript, es un gran recurso para cosas como esta.
fuente