Antes que nada quiero mencionar que sé cómo isNaN()
y cómo Number.isNaN()
trabajo. Estoy leyendo La guía definitiva de David Flanagan y él da un ejemplo de cómo verificar si el valor es NaN
:
x !== x
Esto dará como resultado true
si y solo si x
es así NaN
.
Pero ahora tengo una pregunta: ¿por qué usa una comparación estricta? Porque parece que
x != x
se comporta de la misma manera. ¿Es seguro usar ambas versiones, o me faltan algunos valores en JavaScript que devolverán true
por x !== x
y false
para x != x
?
javascript
nan
Giorgi Nakeuri
fuente
fuente
!==
cheques sobre!=
cheques. Que yo sepa, no hay otro valor dondex != x
. Pero hay dos grupos distintos de desarrolladores de JavaScript: los que prefieren!=
y los que prefieren!==
, ya sea por velocidad, claridad, expresividad, etc.NaN
no es un tipo único, es un número. Es un valor único que no es igual a sí mismo.===
con NaN para señalar que NaN no es igual a sí mismo. No está "equivocado", lo está haciendo como un ejercicio de enseñanza, demostrando que no funciona.Respuestas:
Primero, permítanme señalar que
NaN
es un valor muy especial: por definición, no es igual a sí mismo. Eso proviene del estándar IEEE-754 en el que se basan los números de JavaScript. El valor "no es un número" nunca es igual a sí mismo, incluso cuando los bits coinciden exactamente. (Que no son necesariamente en IEEE-754, permite múltiples valores diferentes "no un número"). Es por eso que incluso aparece; todos los demás valores en JavaScript son iguales a sí mismos,NaN
es simplemente especial.No tu no eres. La única diferencia entre
!==
y!=
es que este último hará una coerción de tipo si es necesario para que los tipos de operandos sean los mismos. Enx != x
, los tipos de los operandos son los mismos, por lo que es exactamente el mismo quex !== x
.Esto queda claro desde el comienzo de la definición de la Operación de igualdad abstracta :
Los primeros dos pasos son fontanería básica. En efecto, el primer paso
==
es ver si los tipos son los mismos y, si es así, hacer en su===
lugar.!=
y!==
son solo versiones negadas de eso.Entonces, si Flanagan está en lo correcto, eso solo
NaN
dará verdad parax !== x
, podemos estar seguros de que también es cierto que soloNaN
dará verdad porx != x
.Muchos programadores de JavaScript usan de manera predeterminada
===
y!==
evitan algunas trampas en torno a la coerción de tipo que hacen los operadores sueltos, pero no hay nada que leer sobre el uso de Flanagan del operador estricto frente al operador suelto en este caso.fuente
4.9.1 - Equality and Inequality Operators
sección y esta parece ser la respuesta. El punto clave para la===
comparación es:If the two values have the same type, test them for strict equality as described above. If they are strictly equal, they are equal. If they are not strictly equal, they are not equal
.a
realidad es una función y no devuelve el mismo valor dos veces? Eso no es lo mismo que un valor para el cual!==
sería cierto, que es lo que preguntó el OP. Es solo una función que devuelve diferentes valores.foo() !== foo()
tampoco es necesariamente cierto, ya quefoo
podría devolver valores diferentes en cada llamada.Para fines de NaN,
!=
y!==
hacer lo mismo.Sin embargo, muchos programadores evitan
==
o!=
en JavaScript. Por ejemplo, Douglas Crockford los considera entre las " partes malas " del lenguaje JavaScript porque se comportan de maneras inesperadas y confusas:fuente
Solo por diversión, permíteme mostrarte un ejemplo artificial donde
x
no estáNaN
pero los operadores se comportan de manera diferente de todos modos. Primero defina:Entonces nosotros tenemos
pero
fuente
foo() != foo()
donde foo devuelve 1 y luego 2. Por ejemplo, los valores no son los mismos, solo compara diferentes valores.Solo quiero señalar que
NaN
no es lo único que producex !== x
sin usar el objeto global. Hay muchas formas inteligentes de desencadenar este comportamiento. Aquí hay uno que usa getters:Como señalan otras respuestas,
==
realiza una coerción de tipo, pero como en otros idiomas y a la par del estándar: NaN indica un error de cálculo y, por buenas razones, no es igual a sí mismo.Por alguna razón más allá de mí, la gente considera que este es un problema con JS, pero la mayoría de los lenguajes que tienen dobles (es decir, C, Java, C ++, C #, Python y otros) exhiben este comportamiento exacto y la gente está bien con eso.
fuente
Como a veces, las imágenes son mejores que las palabras, revise esta tabla (que es la razón por la que hago de esto una respuesta en lugar de un comentario es porque obtiene una mejor visibilidad).
Allí puede ver que la comparación de igualdad estricta (===) solo devuelve verdadero si el tipo y el contenido coinciden, por lo que
Mientras que la comparación de igualdad abstracta (==) verifica solo el contenido * al convertir tipos y luego compararlos estrictamente:
Aunque no está claro, sin consultar a ECMA , qué considera JavaScript al comparar, de una manera que el siguiente código evalúa como verdadero.
fuente