Búsqueda de sitios web

javascript - ¿Cuál es la diferencia entre (NaN != NaN) y (NaN !== NaN)?


Primero que nada quiero mencionar que sé cómo funcionan isNaN() y Number.isNaN(). Estoy leyendo The Definite Guide de David Flanagan y él da un ejemplo de cómo verificar si el valor es NaN:

x !== x

Esto resultará en true si y solo si x es NaN.

Pero ahora tengo una pregunta: ¿por qué usa comparación estricta? Porque parece que

x != x

se comporta de la misma manera. ¿Es seguro usar ambas versiones, o me estoy perdiendo algún valor en JavaScript que devuelva true para x !== x y false para x != x?

Respuesta #1

Primero, permítanme señalar que NaN es un valor muy especial: por definición, no es igual a sí mismo. Esto 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. (Cosa que no necesariamente ocurre en IEEE-754, ya que permite múltiples valores diferentes de "no es un número".) Por eso surge esto; todos los demás valores en JavaScript son iguales a sí mismos, NaN es simplemente especial.

...¿me estoy perdiendo algún valor en JavaScript que devuelva true para x !== x y false para x != x?

No, no lo eres. La única diferencia entre !== y != es que este último hará coerción de tipos si es necesario para que los tipos de los operandos sean iguales. En x != x, los tipos de los operandos son iguales, por lo que es exactamente lo mismo que x !== x.

Esto queda claro desde el comienzo de la definición de la Operación de Igualdad Abstracta:

  1. DevuelveSiAbrupto(x).
  2. DevuelveSiAbrupto(y).
  3. Si Type(x) es el mismo que Type(y), entonces

    Devuelve el resultado de realizar la Comparación de Igualdad Estricta x === y.

  4. ...

Los dos primeros pasos son plomería básica. Así que, en efecto, el primer paso de == es ver si los tipos son iguales y, si es así, hacer === en su lugar. != y !== son solo versiones negadas de eso.

Así que si Flanagan tiene razón en que solo NaN dará verdadero para x !== x, podemos estar seguros de que también es cierto que solo NaN dará verdadero para x != x.

Muchos programadores de JavaScript optan por usar === y !== para evitar algunos problemas relacionados con la coerción de tipos que hacen los operadores laxos, pero no hay nada que interpretar en el uso de operadores estrictos frente a laxos de Flanagan en este caso.

Respuesta #2

Para los propósitos de NaN, != y !== hacen lo mismo.

Sin embargo, muchos programadores evitan == o != en JavaScript. Por ejemplo, Douglas Crockford los considera entre las "malas partes" del lenguaje JavaScript porque se comportan de maneras inesperadas y confusas:

JavaScript tiene dos conjuntos de operadores de igualdad: === y !==, y sus gemelos malvados == y !=. Los buenos funcionan de la manera que esperarías.

...Mi consejo es no usar nunca a los gemelos malvados. En su lugar, siempre usa === y !==.

Respuesta #3

Solo por diversión, déjame mostrarte un ejemplo artificial donde x no es NaN pero los operadores se comportan de manera diferente de todos modos. Primero define:

Object.defineProperty(
  self,
  'x',
  { get: function() { return self.y = self.y ? 0 : '0'; } }
);

Entonces tenemos

x != x // false

pero

x !== x // true

Artículos relacionados