Original article: JavaScript Comparison Operators – How to Compare Objects for Equality in JS

Cuando programamos en JavaScript, puede haber veces en las que necesitemos comparar la igualdad de objetos. El tema es que comparar objetos en JavaScript no es tan fácil.

En este artículo, aprenderás tres formas de comparar la igualdad de objetos en JavaScript.

¡Empecemos!

¿Cuál es la diferencia al comparar tipos de datos primitivos versus tipo de datos no primitivos en JavaScript?

En JavaScript, los tipos de datos pueden dividirse en dos categorías:

  • Primitivos (como números, cadenas de texto o cadena, booleanos, undefined, null o symbol)
  • No primitivos (como los objetos)

Los tipos de datos primitivos refieren a un único valor, por lo que comparar este tipo de datos es relativamente fácil - solo es necesario usar cualquier de los operadores de comparación.

En el siguiente ejemplo, vamos a usar el operador de igualdad estricta, ===, que verifica si los dos operandos son iguales y devuelve un booleano como resultado:

let a = 1;
let b = 1;

console.log(a === b); // true

También es posible asignarle a otra variable, a1, el valor de la variable a y compararlas:

let a = 1;
let b = 1;

let a1 = a;

console.log(a === a1); // true

En el ejemplo anterior, ambas variables apuntan al mismo valor, por lo que el resultado es true.

Pero, al comparar objetos, no es tan fácil:

let a = { name: 'Dionysia', age: 29};
let b = {name: 'Dionysia', age:29};

console.log(a === b); // false

Aunque los dos objetos tienen las mismas propiedades y valores, el resultado de la comparación es false ¿Por qué?

¿Es porque usamos el operador de igualdad estricta, ===? ¿Qué pasa si usamos el operador de igualdad regular, ==?

let a = { name: 'Dionysia', age: 29};
let b = {name: 'Dionysia', age:29};

console.log(a == b); // false

¡Obtuvimos el mismo resultado!

Ambas variables a y b parecieran ser iguales, pero los objetos no son iguales cuando usamos === o ==.

Podríamos pensar que dos objetos que tienen las mismas propiedades con los mismos valores se considerarían iguales.

La razón detrás de este resultado tiene que ver con como JavaScript comprueba la igualdad al comparar datos primitivos y no primitivos:

La diferencia entre tipos de datos primitivos y no primitivos es la siguiente:

  • Los tipos de datos primitivos se comparan por valor.
  • Los tipos de datos no primitivos se comparan por referencia.

En las secciones siguientes, vamos a ver algunas maneras de comparar la igualdad de objetos.

Cómo comparar objetos por referencia en JavaScript

Como vimos en el ejemplo de arriba, al usar == y === nos devuelve false al tratar de comparar objetos por valor:

let a = { name: 'Dionysia', age: 29};
let b = {name: 'Dionysia', age:29};

console.log(a === b); // false

Ambos objetos tienen propiedades y valores idénticos, pero el resultado fue false porque son distintas instancias.

Para comparar objetos por referencia, hay que comprobar si ambos apuntan al mismo lugar en memoria.

Al referenciar a un objeto, se hace referencia a una dirección en memoria.

Veamos un ejemplo:

let a = { name: 'Dionysia', age: 29};

let b = a;


console.log(a === b); // true

En el ejemplo de arriba, gracias a la línea let b = a;, ambas variables tienen la misma referencia y apuntan a la misma instancia del objeto, por lo que el resultado es true:

Cuando asignamos la variable a a b, la dirección de a se copia en b. Esto hace que ambas variables tengan la misma dirección - no el mismo valor.

Con este dicho, la mayoría de las veces, vamos a querer comparar objetos por valor y no por instancia.

Y como vimos, no es posible usar solamente == o === para comparar objetos por valor - esto requiere un poco más de trabajo.

Cómo comparar objetos usando la función JSON.stringify() en JavaScript

Una manera en la que es posible comparar dos objetos por valor es usando la función JSON.stringify()

La función JSON.stringify()  convierte a los objetos en cadenas de texto JSON equivalentes. Entonces, es posible usar cualquier operador de comparación para comparar las cadenas.

let a = { name: 'Dionysia', age: 29};
let b = { name: 'Dionysia', age: 29};

console.log(JSON.stringify(a) === JSON.stringify(b)); // true

La función JSON.stringify() convierte ambos objetos en cadenas JSON y, como ambas variables a y b tienen las mismas propiedades y valores, el resultado es true.

Pero JSON.stringify() no siempre es la mejor solución para comparar objetos por valor, ya que tiene sus limitaciones.

En primer lugar, al usar JSON.stringify(), el orden de las propiedades es importante.

Veamos lo que pasa cuando las propiedades tienen diferente orden.

let a = { age: 29, name: 'Dionysia'};
let b = { name: 'Dionysia', age: 29};

console.log(JSON.stringify(a) === JSON.stringify(b)); //false

En este ejemplo, podríamos pensar que el resultado debería ser true, ya que los valores son los mismos - solo cambiamos el orden de las propiedades.

JSON.stringify() convierte el objeto a cadena de texto, por lo que el orden de las propiedades. Si no se respeta el mismo orden, el resultado será false.

Entonces, JSON.stringify() no es la mejor opción para comparar objetos, ya que no siempre podemos estar seguros del orden de las propiedades.

Otra limitación adicional es que JSON no muestra todos los tipos de datos.

Veamos que pasa cuando el valor de una propiedad es undefined:

let a = { name: 'Dionysia'};
let b = { name: 'Dionysia', age: undefined};

console.log(JSON.stringify(a) === JSON.stringify(b)); //true

En el ejemplo anterior, el resultado es inesperado. El resultado debería haber sido false, pero el resultado devuelto fue true porque JSON ignora aquellas propiedades cuyos valores son undefined.

Cómo comparar objetos usando el método Lodash _.isEqual() en JavaScript

Una solución sofisticada y elegante para comparar objetos por su valor es usar el método _isEqual() de la ya probada librería de JavaScript, Lodash.

Tomemos el ejemplo anterior, en el cual las propiedades tenían el mismo valor pero en diferente orden, y usemos el método _.isEqual()`:

let a = { age: 29, name: 'Dionysia'};
let b = { name: 'Dionysia', age: 29};

console.log(_.isEqual(a, b)); // true

En la sección anterior, el resultado al usar JSON.stringify() era false.

La librería Lodash ofrece una variedad de casos de ejemplo y realiza comparaciones profundas entre dos valores para comprobar si los dos valores son iguales en profundidad.

Conclusión

En este artículo, aprendimos a como comparar la igualdad de objetos en JavaScript.

Vimos tres maneras diferentes de hacerlo y los pros y contras de cada uno. En la duda, la manera más efectiva de comparar objetos es usando la libraría Lodash.

¡Gracias por leer y feliz codeo!