JS: Objetos

Teoría: Fusión

Cuando trabajamos con objetos en JavaScript, muchas veces necesitamos combinar datos de uno dentro de otro. A esta operación se le conoce como fusión o merge y nos permite actualizar un objeto sin necesidad de asignar manualmente cada una de sus propiedades.

¿Por qué necesitamos fusionar objetos?

Imagina que estás desarrollando una aplicación web en la que los usuarios pueden actualizar sus datos personales. Cuando un usuario cambia su nombre o edad en el formulario de configuración, estos datos llegan a la aplicación en forma de un objeto nuevo. Tu tarea es transferir esa información al objeto original que representa al usuario.

Ejemplo:

Supongamos que tenemos este objeto que representa a un usuario registrado:

const user = { name: 'Miguel', email: 'support@codica.io', age: 44 };

Ahora, el usuario edita su información y envía un formulario con estos nuevos datos:

const data = { name: 'Miguel 2', age: 33 };

El resultado que queremos obtener es un objeto actualizado combinando la información original con la nueva:

// { name: 'Miguel 2', email: 'support@codica.io', age: 33 }

Métodos para fusionar objetos

Asignación manual

Una forma simple de actualizar el objeto sería asignar cada propiedad por separado:

user.name = data.name;
user.age = data.age;

// Luego, guardamos el usuario actualizado en la base de datos

Esto funciona si el objeto tiene pocas propiedades, pero ¿qué pasa si tiene muchas? Escribir todas estas asignaciones manualmente puede ser repetitivo y poco eficiente.

Para evitar errores, podríamos verificar primero si la propiedad existe en data antes de sobrescribirla:

if (Object.hasOwn(data, 'name')) {
  user.name = data.name;
}
if (Object.hasOwn(data, 'age')) {
  user.age = data.age;
}

Este método es más seguro, pero sigue siendo muy engorroso cuando hay muchas propiedades.


Usando Object.assign()

JavaScript nos ofrece una solución más elegante y concisa con Object.assign(). Este método toma un objeto base y copia en él todas las propiedades de los objetos que le pasemos como parámetros.

Object.assign(user, data);
console.log(user);
// => { name: 'Miguel 2', email: 'support@codica.io', age: 33 }

¿Cómo funciona Object.assign()?

  1. Toma el primer parámetro (user) y lo modifica directamente.
  2. Copia todas las propiedades del segundo objeto (data) dentro del primero.
  3. Si una propiedad ya existe en el primer objeto, su valor se sobrescribe con el del segundo objeto.
  4. Si una propiedad está solo en el primer objeto, permanece sin cambios.
  5. Si hay propiedades nuevas en el segundo objeto, se agregan al primero.

Otro ejemplo:

const obj1 = { a: 'a', b: 'b' };
const obj2 = { c: 'c', b: 'v' };

Object.assign(obj1, obj2);
console.log(obj1);
// => { a: 'a', b: 'v', c: 'c' }

Aquí, b fue sobrescrito con el valor del segundo objeto (v), mientras que a quedó igual y c se agregó.


Limitaciones de Object.assign()

Object.assign() realiza una fusión superficial, lo que significa que no combina objetos anidados. En su lugar, los reemplaza completamente:

const obj1 = { a: { a: 1 } };
const obj2 = { a: { b: 1 } };

Object.assign(obj1, obj2);
console.log(obj1);
// => { a: { b: 1 } }  <- Se perdió el valor original de `a: 1`

Si queremos hacer una fusión profunda (es decir, conservar propiedades de los objetos internos en lugar de reemplazarlos), podemos usar la biblioteca lodash:

import _ from 'lodash';

_.merge(obj1, obj2);
console.log(obj1);
// => { a: { a: 1, b: 1 } }

_.merge() combina de manera recursiva los objetos internos en lugar de sobrescribirlos por completo.


Precauciones al usar la fusión de objetos

La fusión es una herramienta poderosa, pero hay que usarla con cuidado.
Algunos aspectos a considerar:
  1. Sobrescritura accidental: Si un objeto contiene propiedades críticas (como el saldo de una cuenta bancaria), hay que asegurarse de que no sean modificadas accidentalmente.
  2. Datos maliciosos: En formularios web, un usuario podría enviar más datos de los que se esperaban. Si fusionamos objetos sin validación, podrían sobrescribirse propiedades importantes.
  3. Efectos colaterales: Object.assign() modifica directamente el primer objeto, por lo que si necesitas mantener el objeto original intacto, primero debes hacer una copia:
const newUser = Object.assign({}, user, data);

Otra opción aún más sencilla es usar el spread operator (...), que crea un nuevo objeto en lugar de modificar el existente:

const newUser = { ...user, ...data };
console.log(newUser);
// => { name: 'Miguel 2', email: 'support@codica.io', age: 33 }

Resumen

  • La fusión de objetos permite combinar datos de un objeto dentro de otro.
  • Object.assign(objDestino, objFuente) copia las propiedades de un objeto a otro y sobrescribe las propiedades existentes.
  • La fusión superficial de Object.assign() reemplaza los objetos anidados en lugar de combinarlos.
  • Para una fusión profunda, se puede usar _.merge() de lodash.
  • Hay que ser cuidadoso con qué datos se fusionan para evitar sobrescribir valores importantes por accidente.
  • Si se quiere mantener el objeto original intacto, es mejor hacer una copia con Object.assign({}, obj1, obj2) o el operador spread ({ ...obj1, ...obj2 }).

Completado

0 / 13