"El buen diseño es obvio. El gran diseño es transparente"
- Joe Sparano

Como fusionar objetos en Javascript

4 minutos de lectura
Fecha: 26/8/2021

Es posible que a lo largo del desarrollo de nuestros proyectos nos encontremos con la necesidad de fusionar objetos en Javascript.

Esto es más habitual de lo que pudiera parecer, imaginemos que estamos trabajando con una aplicación que muestra datos en tiempo real, que estos llegan por un socket y hay que ir refrescándolos. Lo más habitual es que lleguen solo aquellos que cambian, con lo cual el objeto que tenemos solo es un fragmento que debemos fusionar con el actual que si está completo.

O pensemos en que estamos creando un plugin con una serie de parámetros por defecto que después el usuario podrá «machacar» con su configuración específica.

Tarde o temprano nos vamos a ver en la necesidad de fusionar objetos en Javascript, por eso quiero mostrar cuales son algunas maneras de hacerlo. Y también poder ver las diferencias que presentan y las ventajas que tiene hacerlo de una u otra manera.

Para comenzar os pido que prestéis atención a estos dos objetos que hay a continuación…

// objeto 1
let objeto1 = {
  marca: 'Ford',
  modelo: 'GT 40',
  año: 2014,
  longitud: 4779,
  anchura: 2003,
  altura: 1109,
}

// objeto 2
let objeto2 = {
  marca: 'Ford',
  modelo: 'GT 40',
  año: 2017,
  anchura: 2000,
  velocidad: 347,
  peso: 1460,
}

Como se puede observar tienen varias propiedades que son iguales, dos de ellas además tienen el mismo contenido como serían la marca y el modelo, pero hay otras dos en las que el contenido es distinto.

Vamos a aplicar distintos métodos disponibles que tenemos para fusionar estos objetos y vemos cual es el resultado.  

Usando el operador Spread

El operador spread (…) fue introducido en el standard ES2018 también llamado ES9, os dejo aquí la propuesta para que veáis todo lo que se puede hacer con él. Es decir que tu navegador si no esta actualizado podría no soportarlo. Dejo también el link a caniuse para que veas desde que versiones ya lo soportan.

Esta sería para mi la manera más limpia de hacerlo, la sintaxis es muy elegante y tiene ciertas ventajas. Vamos a ver como funciona…

const objeto3 = { ...objeto1, ...objeto2 };

// objeto3
{
  marca: "Ford",
  modelo: "GT 40",
  "año": 2017,
  longitud: 4779,
  anchura: 2000,
  altura: 1109,
  velocidad: 347,
  peso: 1460 
}

Como podemos ver una de las ventajas es que aquí los objetos originales que se fusionan no se modifican, sino que mas bien declaramos un nuevo objeto donde se realiza el mergeo.

Además de esto podemos observar como el objeto que está mas a la derecha (en nuestro caso objeto2) es el que gana en caso de conflicto. Vemos como por ejemplo la anchura marca 2000 en vez de 2003. Las propiedades que eran distintas en ambos acaban tomando el valor del objeto2.

Usar el método nativo Assign

Este método esta disponible desde el standard ES2015 también llamado ES6. Ya es tan antiguo y tendrías que tener una versión tan antigua del navegador para que no lo soportara, que vamos a tratarlo como disponible para cualquiera.

Todos los objetos tienen una serie de métodos que de forma nativa podemos usar, en este caso assign nos permite Fusionar objetos en Javascript, veamos como usarlo…

Object.assign(objeto1, objeto2);

//objeto 1
{
  marca: "Ford",
  modelo: "GT 40",
  "año": 2017,
  longitud: 4779,
  anchura: 2000,
  altura: 1109,
  velocidad: 347,
  peso: 1460
}

//objeto 2
{
  marca: "Ford",
  modelo: "GT 40",
  "año": 2017,
  anchura: 2000,
  velocidad: 347,
  peso: 1460
}

 

Este método al igual el operador spread machaca con el objeto2 las propiedades del objeto1 que tienen distinto valor. Pero ya hay matices, por ejemplo que acabamos de perder el objeto1 original, ya que después de usar el método assign este quedo modificado con el resultado del mergeo.

No pienses que puedes declarar un nuevo objeto para guardar el resultado y que no afecte a los originales, aunque lo hicieras de esta manera:

const objeto5 = Object.assign(objeto1, objeto2);

De hacerlo así objeto5 y objeto1 tendría ambos el resultado de la fusión, eso para mi ya es un punto en contra. Porque si entendemos que el objeto1 es el maestro donde están todos los datos y el objeto2 es un fragmento que tiene el contenido parcial para actualizarlo, una vez ejecutado el assign ya no vas a poder saber que tenias antes de fusionarlos (y hay casos donde podría necesitarse).

Pero este detalle lo podemos arreglar metiendo como primer parámetro del método un objeto vacío y luego los demás, de la siguiente manera…

const objeto5 = Object.assign({}, objeto1, objeto2);

Como truco esta bien, y ahora si que podríamos hacer lo mismo que con el operador spread, pero personalmente la sintaxis no me gusta mucho, es menos descriptivo y en caso de trabajar en equipo habrá gente que no entienda a la primera que estas intentando hacer.

Usando un bucle for-in para añadir las propiedades

Esta sería la manera de hacerlo en ES5.

El bucle for-in sirve para recorrer las propiedades de un objeto, con esto ya tenemos mucho avanzado. Y también nos vale para fusionar objetos en Javascript, lo usaríamos así.

for (var attrname in objeto2) { objeto1[attrname] = objeto2[attrname]; }

// objeto 1
{
  marca: "Ford",
  modelo: "GT 40",
  "año": 2017,
  longitud: 4779,
  anchura: 2000,
  altura: 1109,
  velocidad: 347,
  peso: 1460
}

Mismo resultado que con spread y assign, pero volvemos a tener el problema de que estaríamos machacando el objeto1 y perderíamos el estado que teníamos antes de fusionarlo.

Pero podemos usar la misma estrategia que antes y usar un objeto vacío como base…

var objeto3 = {};
for (var attrname in objeto1) { objeto3 [attrname] = objeto1[attrname]; }
for (var attrname in objeto2) { objeto3 [attrname] = objeto2[attrname]; }

Si estabas pensando en igualar objeto3 a objeto1 eso no iba a funcionar en el caso de los objetos (estarías copiando la referencia no el objeto como tal). Por eso el primer bucle for-in de este truco es para hacer un clonado del objeto.

Recordar que estamos hablando de objetos cuyas propiedades nos son otros objetos, si tuviéramos mas de un nivel ya habría que hablar de otras cosas, pero no es el propósito del post.

Usando jQuery.extend

Ahora ya no hablamos de métodos y operadores nativos del lenguaje, pero como jQuery esta súper extendido vamos a mencionarlo. Funciona igual que el assign…

var objeto3 = $.extend({}, objeto1, objeto2);

(Ya puse la manera de conservar los originales)

 

 

Y hasta aquí el post, hay muchas maneras de fusionar objetos en Javascript, espero que con esto tengas la información para decidirte por aquel que mas se adapte a lo que buscas.