Solución:
isNaN()
y Number.isNaN()
ambos prueban si un valor es (o, en el caso de isNaN()
, se puede convertir a un valor de tipo numérico que representa) el NaN
valor. En otras palabras, “NaN” no significa simplemente “este valor no es un número”, sino que significa específicamente “este valor es un numérico Valor no numérico según IEEE-754 “.
La razón por la que todas sus pruebas anteriores devuelven falso es porque todos los valores dados se pueden convertir a un valor numérico que no es NaN
:
Number('') // 0
Number(' ') // 0
Number(true) // 1
Number(false) // 0
Number([0]) // 0
La razón isNaN()
está “roto” se debe a que, aparentemente, no se supone que se produzcan conversiones de tipos cuando se prueban valores. Ese es el problema Number.isNaN()
está diseñado para abordar. En particular, Number.isNaN()
voluntad solamente intentar comparar un valor con NaN
si el valor es un valor de tipo numérico. Cualquier otro tipo devolverá falso, incluso si son literalmente “no un número”, porque el escribe del valor NaN
es número. Consulte los documentos de MDN respectivos para isNaN()
y Number.isNaN()
.
Si simplemente desea determinar si un valor es del tipo numérico, incluso si ese valor es NaN
, usar typeof
en lugar de:
typeof 'RAWRRR' === 'number' // false
No, el original isNaN
está roto. No entiendes el punto de isNaN
.
El propósito de estas dos funciones es determinar si algo tiene el valor NaN
. Esto se proporciona porque something === NaN
siempre será false
y por lo tanto no se puede utilizar para probar esto. (nota al margen: something !== something
es en realidad una prueba confiable, aunque contraria a la intuición, para NaN
)
La razón isNaN
está roto es que puede volver true
en los casos en que un valor no es realmente NaN
. Esto se debe a que primero convierte el valor en un número.
Entonces
isNaN("hello")
es true
, aunque "hello"
no es NaN
.
Si desea verificar si un valor en realidad es un número finito, puede usar:
Number.isFinite(value)
Si desea probar si un valor es un número finito o una representación de cadena de uno, puede usar:
Number.isFinite(value) || (Number.isFinite(Number(value)) && typeof value === 'string')
La diferencia clave entre los dos es que el global isNaN(x)
la función realiza una conversión del parámetro x
a un número. Entonces
isNaN("blabla") === true
porque Number("blabla")
resultados en NaN
Hay dos definiciones de “no es un número” aquí y quizás ahí radica la confusión. Number.isNaN(x)
solo devuelve verdadero para la definición de la especificación de punto flotante IEEE 754 de No es un número, por ejemplo:
Number.isNaN(Math.sqrt(-1))
en lugar de determinar si el objeto que se pasa es de tipo numérico o no. Algunas formas de hacerlo son:
typeof x === "number"
x === +x
Object.prototype.toString.call(x) === "[object Number]"