Cuando comparamos objetos en JavaScript estamos comparando que la referencia sea la misma (que ambos objetos apunten a la misma dirección de memoria), no los valores.
const mauricio = {
name: "Mauricio"
};
const anotherPerson = {
name: "Mauricio"
};
console.log( mauricio == anotherPerson ); //falseconsole.log( mauricio === anotherPerson ); //false//aunque los valores son los mismos, la referencia no lo esconst anotherPerson3 = {
...mauricio
};
console.log( mauricio == anotherPerson3 ); //false//la refencia no es la mismaconst anotherPerson2 = mauricio;
console.log( mauricio == anotherPerson2 ); //true//la referencia de memoria es la misma
El lenguaje no tiene de forma nativa una función o método para determinar que dos objetos tengan el mismo valor. Hay distintas soluciones que podemos implementar, aquí las veremos yendo desde las más básicas hasta las más complejas y robustas.
const person1 = {
name: "David",
age: "Ortega"
};
const person2 = {
name: "David",
age: "Ortega"
};
console.log( JSON.stringify( person1 ) === JSON.stringify( person2 ) ); //true
Lo que hacemos aquí es transformar los objetos en strings (los cuales sí son comparables por su valor). Es una solución valida, pero en el caso de que los atributos estén en otro orden dará false
porque el string sería distinto.
const person1 = {
age: "Ortega",
name: "David"
};
const person2 = {
name: "David",
age: "Ortega"
};
console.log( JSON.stringify( person1 ) === JSON.stringify( person2 ) ); //false
esto último hace que esta no sea una implementación muy robusta.
Lo que haremos será colocar los objetos que queramos comparar en un array. Luego con el método filter
retornaremos todos los objetos que cumplan con las condiciones establecidas, si retorna dos objetos entonces sabemos que tienen el mismo valor.
const person1 = {
age: "Ortega",
name: "David"
};
const person2 = {
name: "David",
age: "Ortefga"
};
let objs = [ person1, person2 ];
let objComparasion = objs.filter( (obj) => {
return (
obj.name === person1.name &&
obj.age === person1.age
);
});
if ( objComparasion.length === 2 ) console.log( true );
elseconsole.log( false );
Con esta implementación solucionamos el problema de la anterior; ya que no importa en qué orden están los atributos, pero esta implementación tiene sus propios problemas: no es agnóstico a la estructura del objeto porque tenemos que escribir manualmente cada atributo.
Construiremos una función para comparar nuestros objetos.
subirá el nivel de complejidad.
keys
de cada objeto.keys
(atributos), lógicamente, si no tienen la misma cantidad no son iguales entonces retornamos false
.key
sea el mismo en cada objeto, sino es así retornara false
.const person1 = {
name: "David",
age: "Ortega"
};
const person2 = {
name: "David",
age: "Ortega"
};
functiondefinitiveComparasion( obj1, obj2 )
{
keys1 = Object.keys( obj1 );
keys2 = Object.keys( obj2 );
if ( keys1.length !== keys2.length ) returnfalse;
for ( key of keys1 ) {
let val1 = obj1[key];
let val2 = obj2[key];
if ( val1 !== val2 ) returnfalse;
}
returntrue;
}
console.log( definitiveComparasion( person1, person2 ) ); //true
Esta es una gran solución a nuestro problema: conseguimos que fuera agnóstica al objeto; pero… en JS es bastante normal tener objetos dentro de objetos y esta función no nos resuelve ese problema.
Usaremos como base la función anterior y le agregaremos un par de líneas más. Primero debemos identificar cuando un valor es un objeto para lo que crearemos una función y además tenemos que ver verificar que el objeto que hay dentro del objeto sea igual al objeto dentro del otro objeto ¿Te suena a algo? Si, recursividad, usaremos recursividad en esta función.
isObject
no hay mucho que explicar, es algo que se sale del tema del tutorial entonces solo créeme… funciona.true
si el valor para la key
actual en ambos objetos es un objeto y false
si no es así.functionisObject( obj )
{
returnObject.prototype.toString.call(obj) === '[object Object]';
}
functiongodsComparasion( obj1, obj2 )
{
keys1 = Object.keys( obj1 );
keys2 = Object.keys( obj2 );
if ( keys1.length !== keys2.length ) returnfalse;
for ( key of keys1 ) {
let val1 = obj1[key];
let val2 = obj2[key];
let areObjects = isObject( val1 ) && isObject( val2 );
if (
( areObjects && !godsComparasion( val1, val2 ) ) ||
( !areObjects && val1 !== val2 )
) returnfalse;
}
returntrue;
}
const person3 = {
name: "David",
age: "Ortega",
family: {
dad: "Rodrigo",
mom: "Estela"
}
};
const person4 = {
name: "David",
age: "Ortega",
family: {
dad: "Rodrigo",
mom: "Estela"
}
};
console.log( godsComparasion( person4, person3 ) ); //true
Esta solución es realmente robusta. Incluso podemos comparar objetos con objetos dentro.
Te invito a que intentes modificar esta función para poder comparar arrays dentro de un objeto y compartir tu solucion en los comentarios.
me gustó este tutorial 😃
Gracias por este tutorial!!
muy bueno hermano. felicitaciones