¿Cómo puedo fusionar dinámicamente las propiedades de dos objetos JavaScript?
Necesito poder fusionar dos objetos JavaScript (muy simples) en tiempo de ejecución. Por ejemplo me gustaría:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
¿Existe una forma integrada de hacer esto? No necesito recursividad y no necesito fusionar funciones, solo métodos en objetos planos.
Método estándar ECMAScript 2018
Usarías la extensión de objetos :
let merged = {...obj1, ...obj2};
merged
ahora es la unión de obj1
y obj2
. Las propiedades en obj2
sobrescribirán las de obj1
.
/** There's no limit to the number of objects you can merge.
* Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};
Aquí también está la documentación de MDN para esta sintaxis. Si está utilizando babel, necesitará el complemento @babel/plugin-proposal-object-rest-spread para que funcione (este complemento está incluido en @babel/preset-env
, en ES2018 ).
Método estándar ECMAScript 2015 (ES6)
/* For the case in question, you would do: */
Object.assign(obj1, obj2);
/** There's no limit to the number of objects you can merge.
* All objects get merged into the first object.
* Only the object in the first argument is mutated and returned.
* Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);
(ver Referencia de JavaScript de MDN )
Método para ES5 y versiones anteriores
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
Tenga en cuenta que esto simplemente agregará todos los atributos de obj2
que obj1
podrían no ser los que desea si aún desea utilizar el archivo sin modificar obj1
.
Si está utilizando un marco que arruina todos sus prototipos, entonces debe ser más sofisticado con comprobaciones como hasOwnProperty
, pero ese código funcionará en el 99% de los casos.
Función de ejemplo:
/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
*/
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
Además: consulte este programa para ver la diferencia entre los literales de objetos de sintaxis extendida y Object.assign.
jQuery también tiene una utilidad para esto: http://api.jquery.com/jQuery.extend/ .
Tomado de la documentación de jQuery:
// Merge options object into settings object
var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
// Now the content of settings object is the following:
// { validate: true, limit: 5, name: "bar" }
El código anterior mutará el objeto existente llamado settings
.
Si desea crear un nuevo objeto sin modificar ninguno de los argumentos, utilice esto:
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
/* Merge defaults and options, without modifying defaults */
var settings = $.extend({}, defaults, options);
// The content of settings variable is now the following:
// {validate: true, limit: 5, name: "bar"}
// The 'defaults' and 'options' variables remained the same.
Harmony ECMAScript 2015 (ES6) especifica Object.assign
cuál hará esto.
Object.assign(obj1, obj2);
La compatibilidad actual con los navegadores está mejorando , pero si está desarrollando para navegadores que no son compatibles, puede utilizar un polyfill .