Menu

Operadores de igualdad en JavaScript: == vs === y Object.is

Cómo funciona la igualdad en JavaScript: comparación estricta frente a comparación con coerción, las rarezas de ==, el caso de NaN y los objetos, y cuándo conviene usar Object.is.

Las dos formas de preguntar "¿esto es igual?"

En JavaScript tenemos dos operadores de igualdad: === (estricta) y == (débil o con coerción). A simple vista parecen lo mismo, pero su comportamiento es muy distinto.

index.js
Output
Click Run to see the output here.

=== verifica que ambos operandos sean del mismo tipo y del mismo valor. En cambio, == primero convierte los operandos a un tipo común y luego compara. Esa conversión —la coerción de tipos— es la responsable de casi toda la mala fama que arrastra la igualdad en JavaScript.

En resumen: usa === por defecto. La versión larga vale la pena leerla al menos una vez, para saber a qué estás renunciando cuando eliges el otro.

Igualdad estricta: lo que casi siempre quieres usar

=== devuelve true únicamente cuando ambos lados coinciden en tipo y valor. Sin coerción, sin sorpresas:

index.js
Output
Click Run to see the output here.

Si los tipos no coinciden, el resultado es false al instante. Si coinciden, JavaScript compara los valores. En los primitivos se compara el valor; en los objetos se compara la referencia (ahora entramos en detalle).

!== es el operador de desigualdad estricta y aplica las mismas reglas, pero al revés.

Igualdad débil: coerción de tipos disfrazada

== permite que ambos lados sean de tipos distintos. Antes de comparar, hace todo un baile de coerción para intentar que encajen:

index.js
Output
Click Run to see the output here.

Las reglas exactas están en la especificación y no son horribles, pero recordarlas en plena depuración ya es otra historia. Que "0" == falsetrue pilla desprevenidos incluso a desarrolladores con experiencia. Lo mismo pasa con [] == false (también true, porque el array se convierte a "", que a su vez se convierte a 0).

Por eso la mayoría de las guías de estilo —y la regla eqeqeq de ESLint— recomiendan usar === por defecto. Tecleas un carácter más a cambio de reglas que sí puedes recordar.

El único patrón útil con ==

Hay un solo idiom de igualdad débil que vale la pena conocer: x == null devuelve true cuando x es null o undefined, y false en cualquier otro caso.

index.js
Output
Click Run to see the output here.

El equivalente estricto es x === null || x === undefined, que funciona pero queda más ruidoso. Muchos proyectos permiten == null como la única excepción aceptada. Elige una regla y aplícala siempre igual.

Los objetos se comparan por referencia

Cuando hablamos de objetos, arrays y funciones, tanto === como == hacen la misma pregunta: "¿Ambos lados apuntan al mismo objeto en memoria?". No preguntan "¿tienen el mismo contenido?".

index.js
Output
Click Run to see the output here.

Dos objetos literales con el mismo contenido siguen siendo dos objetos distintos. A todos nos pilla desprevenidos al menos una vez.

Si lo que quieres es comparar por valor, tienes que escribir tu propio helper, tirar de una librería (lodash.isequal) o, para objetos planos sencillos, serializar con JSON.stringify:

index.js
Output
Click Run to see the output here.

JSON.stringify solo sirve para datos simples: ignora funciones, undefined, símbolos y no garantiza el mismo orden de claves entre motores en todos los casos. Es un truco rápido, no una solución general.

NaN no es igual a nada, ni siquiera a sí mismo

NaN ("not a number") es el valor que devuelve JavaScript cuando una operación numérica no tiene un resultado con sentido: 0/0, Number("abc"), Math.sqrt(-1). Ambos operadores de igualdad devuelven false cuando cualquiera de los lados es NaN, incluso cuando los dos lo son:

index.js
Output
Click Run to see the output here.

Para detectar NaN, usa Number.isNaN(value). Evita la función global isNaN de toda la vida, porque primero convierte su argumento, así que isNaN("hello") devuelve true, algo que casi nunca es lo que buscas.

Object.is: casi como ===, pero con dos matices

Object.is(a, b) se comporta igual que ===, salvo en dos casos puntuales:

index.js
Output
Click Run to see the output here.

La mayoría de las veces === es lo que quieres. Recurre a Object.is solo cuando necesites tratar NaN como igual a sí mismo, o distinguir entre +0 y -0. Ambos casos son poco frecuentes, pero a veces importan: aparecen en código numérico y en internals de frameworks (por ejemplo, React usa Object.is para comparar el estado).

Los operadores de desigualdad siguen la misma lógica

!== es estricto, != es flexible (hace coerción de tipos), y aplica el mismo consejo:

index.js
Output
Click Run to see the output here.

Por defecto, usa !==. Si ya permites == null en tu código, también puedes admitir su contraparte != null para comprobar "ni null ni undefined".

Checklist para comparar valores en JavaScript

Cuando necesites comparar dos valores, repasa esta lista:

  • ¿Primitivos del mismo tipo? Usa ===.
  • ¿Quieres detectar null o undefined? x == null sirve si tu guía de estilo lo acepta; si no, tira de x === null || x === undefined.
  • ¿Necesitas detectar NaN? Number.isNaN(x).
  • ¿Comparar objetos por identidad (misma referencia)? === hace justo eso.
  • ¿Comparar objetos por contenido? Escribe una función auxiliar, usa una librería o serializa. Los operadores nativos no te van a ayudar aquí.

Quédate con ===, reserva == como herramienta puntual para el caso == null, y te ahorrarás la mayoría de las rarezas de la igualdad en JavaScript que llenan las FAQ del lenguaje.

Siguiente paso: los operadores

La igualdad es solo una parte del repertorio de operadores de JavaScript. En el próximo artículo repasamos el resto: aritméticos, lógicos, de asignación y las versiones abreviadas que vas a usar día a día al programar.

Preguntas frecuentes

¿Cuál es la diferencia entre == y === en JavaScript?

=== es la igualdad estricta: devuelve true solo si ambos operandos son del mismo tipo y tienen el mismo valor. == es la igualdad con coerción: antes de comparar, convierte los operandos al mismo tipo. Por eso 1 === '1' da false, pero 1 == '1' da true, porque el == convierte primero la cadena a número.

¿Conviene usar siempre === en JavaScript?

Como norma general, sí. === es predecible y sus reglas caben en la cabeza sin esfuerzo. La excepción habitual es x == null, que resulta muy cómoda porque detecta a la vez null y undefined. De hecho, la mayoría de linters (como la regla eqeqeq de ESLint) obligan a usar === y permiten ese patrón como excepción opcional.

¿Por qué NaN === NaN devuelve false?

El estándar IEEE 754 establece que NaN no es igual a nada, ni siquiera a sí mismo. Por eso cualquier operador de igualdad devuelve false cuando hay un NaN por medio. Para comprobar si un valor es NaN, usa Number.isNaN(x), o bien Object.is(NaN, NaN), que sí devuelve true.

¿Cómo comparo dos objetos por igualdad en JavaScript?

Tanto == como === comparan los objetos por referencia, no por su contenido. Por eso {a: 1} === {a: 1} es false: son dos objetos distintos en memoria. Para comparar por valor tienes que escribir tu propia función, recurrir a una librería como isEqual de Lodash, o serializar con JSON.stringify si son objetos planos sencillos.

Aprende a programar con Coddy

COMENZAR