Command Palette

Search for a command to run...

Object.is() vs ===: Comparación de Valores en JavaScript

Descubre las diferencias entre Object.is() y el operador de igualdad estricta ===, y aprende cuándo usar cada uno para comparar valores de forma precisa.

Lectura: 12 min
Nivel: Intermedio

TL;DR - Resumen rápido

  • Object.is() es similar a === pero con dos diferencias importantes en casos especiales
  • Object.is(NaN, NaN) retorna true, mientras que NaN === NaN retorna false
  • Object.is(+0, -0) retorna false, mientras que +0 === -0 retorna true
  • Para todos los demás valores, Object.is() se comporta idéntico a ===
  • Object.is() no realiza coerción de tipos, al igual que ===
  • Útil cuando necesitas comparaciones precisas de NaN o distinguir entre +0 y -0

Introducción a Object.is()

Object.is() es un método introducido en ES6 que realiza comparación de igualdad de valores similar al operador de igualdad estricta (===), pero con un comportamiento más predecible en dos casos especiales: la comparación de NaN consigo mismo y la distinción entre +0 y -0. Representa la forma más precisa de comparar valores en JavaScript según el algoritmo "SameValue".

A diferencia del operador == que realiza coerción de tipos, tanto Object.is() como === no convierten tipos antes de comparar. La diferencia principal entre Object.is() y === radica en cómo manejan estos casos edge que han sido históricamente problemáticos en JavaScript: NaN y los ceros con signo.

Algoritmo SameValue

Object.is() implementa el algoritmo "SameValue" de la especificación ECMAScript, que define igualdad de la forma más estricta posible. Es la misma comparación que JavaScript usa internamente en operaciones como Map keys y Set values.

Sintaxis y Uso Básico de Object.is()

Object.is() acepta dos argumentos y retorna un booleano indicando si los valores son iguales según el algoritmo SameValue. La sintaxis es simple y directa, similar a usar el operador === pero como una función.

sintaxis-basica.js
Loading code...

Para la mayoría de valores primitivos y referencias a objetos, Object.is() se comporta exactamente igual que ===. Compara números, strings, booleanos, null, undefined y referencias a objetos de la misma manera. La diferencia solo aparece en los dos casos especiales que veremos a continuación: NaN y los ceros con signo.

Diferencias Clave con el Operador ===

Aunque Object.is() y === son muy similares, tienen dos diferencias importantes que los hacen comportarse distinto en casos edge específicos. Estas diferencias pueden parecer menores, pero son cruciales en ciertos contextos matemáticos y de precisión.

Caso Especial: Comparación de NaN

NaN (Not-a-Number) es un valor especial en JavaScript que tiene la propiedad única de no ser igual a sí mismo cuando se compara con ===. Esta peculiaridad viene de la especificación IEEE 754 para números de punto flotante. Object.is() corrige este comportamiento contra-intuitivo.

comparacion-nan.js
Loading code...

Object.is(NaN, NaN) retorna true, lo cual es más intuitivo y útil en muchos casos. Antes de Object.is(), la única forma de verificar si un valor es NaN era usando Number.isNaN() o la comparación x !== x (que aprovecha que NaN es el único valor no igual a sí mismo). Object.is() proporciona una forma más clara y semánticamente correcta de comparar NaN.

Por qué NaN !== NaN

El comportamiento de NaN !== NaN proviene del estándar IEEE 754 para aritmética de punto flotante, que especifica que cualquier comparación con NaN debe retornar false (excepto !=). JavaScript mantiene esta convención para compatibilidad, pero Object.is() ofrece una comparación más práctica.

Caso Especial: Distinción entre +0 y -0

JavaScript distingue entre cero positivo (+0) y cero negativo (-0) internamente, aunque en la mayoría de operaciones se comportan idénticamente. El operador === considera ambos iguales, mientras que Object.is() los distingue correctamente.

comparacion-ceros.js
Loading code...

Aunque +0 y -0 se comportan igual en la mayoría de operaciones matemáticas, existen casos donde la distinción importa, especialmente en cálculos científicos o cuando la dirección de aproximación a cero tiene significado. Object.is() permite detectar esta diferencia, mientras que === la ignora. Puedes verificar el signo de un cero usando 1/n: 1/+0 es Infinity, mientras que 1/-0 es -Infinity.

Cuándo importa el signo del cero

En la mayoría de código JavaScript, la distinción entre +0 y -0 es irrelevante. Sin embargo, en algoritmos matemáticos complejos, física computacional, o cuando trabajas con límites y aproximaciones, el signo puede tener significado semántico importante.

Comparación de Referencias a Objetos

Para objetos, arrays y funciones, tanto Object.is() como === comparan referencias, no contenido. Dos objetos con las mismas propiedades y valores no son iguales a menos que sean exactamente la misma referencia en memoria.

comparacion-referencias.js
Loading code...

Este comportamiento es idéntico entre Object.is() y ===. Ambos comparan si las referencias apuntan al mismo objeto en memoria, no si los objetos tienen el mismo contenido. Para comparar contenido de objetos, necesitas implementar una función de comparación profunda o usar bibliotecas especializadas. Object.is() no ofrece ventaja sobre === para comparación de objetos.

¿Cuándo Usar Object.is() en Lugar de ===?

En la mayoría de casos, el operador === es suficiente y más idiomático. Sin embargo, hay situaciones específicas donde Object.is() es la herramienta correcta. La decisión depende de si necesitas el comportamiento especial con NaN o ceros con signo.

cuando-usar.js
Loading code...

Usa Object.is() cuando necesites comparar valores que pueden ser NaN (útil en validaciones matemáticas o al trabajar con resultados de parseFloat/parseInt), cuando el signo del cero importa en tu dominio, o cuando implementas algoritmos que requieren la semántica SameValue. Para código general, === es más común y tiene mejor soporte en herramientas de análisis estático.

  • Cuando necesitas verificar si un valor es NaN de forma semántica
  • En algoritmos matemáticos donde el signo de cero es significativo
  • Al implementar estructuras de datos como Map/Set internamente
  • Cuando escribes polyfills o código que imita comportamiento de especificación

Polyfill para Object.is()

Aunque Object.is() tiene excelente soporte en navegadores modernos, si necesitas compatibilidad con navegadores antiguos, puedes implementar un polyfill que replica el comportamiento exacto usando las características que ya existen en JavaScript.

polyfill.js
Loading code...

Este polyfill implementa los dos casos especiales: para NaN, verifica si ambos valores son NaN usando x !== x (la única forma pre-ES6 de detectar NaN de manera confiable); para distinguir +0 y -0, usa la división 1/x que retorna Infinity o -Infinity dependiendo del signo. Para todos los demás casos, simplemente usa === que ya tiene el comportamiento correcto.

Soporte en navegadores

Object.is() tiene excelente soporte en todos los navegadores modernos desde 2015. Solo necesitas el polyfill si debes soportar Internet Explorer 11 o versiones antiguas de navegadores móviles. Para proyectos modernos, puedes usar Object.is() directamente sin preocupaciones.

Comparación: ==, === y Object.is()

JavaScript ofrece tres formas principales de comparar valores: el operador de igualdad abstracta (==), el operador de igualdad estricta (===), y Object.is(). Cada uno tiene comportamientos distintos que los hacen apropiados para diferentes situaciones.

comparacion-tres-metodos.js
Loading code...

La regla general es: usa === para la mayoría de comparaciones (no hace coerción de tipos), evita == excepto para verificar null/undefined explícitamente, y usa Object.is() solo cuando necesites el comportamiento especial con NaN o ceros con signo. La coerción de tipos de == puede causar bugs sutiles, por lo que === es casi siempre la opción correcta en código moderno.

  • <strong>==</strong> (igualdad abstracta): Realiza coerción de tipos, generalmente evitar
  • <strong>===</strong> (igualdad estricta): No coerción, usa esto por defecto
  • <strong>Object.is()</strong>: Como === pero con NaN === NaN true y +0 !== -0

Casos de Uso Prácticos de Object.is()

Aunque Object.is() es menos común que ===, hay escenarios reales donde es la herramienta correcta. Estos casos suelen involucrar validaciones matemáticas, implementación de estructuras de datos, o código que necesita seguir la especificación ECMAScript al pie de la letra.

casos-uso-practicos.js
Loading code...

Los casos de uso más comunes incluyen: validar resultados de operaciones matemáticas que pueden producir NaN, implementar caches o memoización donde NaN puede ser una clave válida, comparar valores en algoritmos de ordenamiento o búsqueda donde la precisión es crítica, y al replicar el comportamiento interno de Map/Set que usa SameValue para comparar claves.

Object.is() en React y frameworks

Algunos frameworks modernos como React usan Object.is() internamente para comparar valores en hooks como useEffect y useMemo. Esto garantiza que NaN sea tratado consistentemente y evita re-renders innecesarios cuando el estado contiene NaN.

Resumen: Object.is() vs ===

Conceptos principales:

  • Object.is() implementa el algoritmo SameValue de ECMAScript
  • Object.is(NaN, NaN) es true, mientras que NaN === NaN es false
  • Object.is(+0, -0) es false, mientras que +0 === -0 es true
  • Para todos los demás valores, comportamiento idéntico a ===
  • No realiza coerción de tipos, al igual que ===
  • Compara referencias en objetos, no contenido profundo

Mejores prácticas:

  • Usar === como operador de comparación por defecto
  • Usar Object.is() cuando necesites comparar NaN correctamente
  • Usar Object.is() si el signo de cero es significativo
  • Evitar == excepto para verificaciones null/undefined explícitas
  • En código matemático complejo, considerar Object.is() para precisión
  • Documentar por qué usas Object.is() en lugar de === para claridad