¿Cómo puedo fusionar dinámicamente las propiedades de dos objetos JavaScript?

Resuelto JC Grubbs asked hace 15 años • 69 respuestas

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.

JC Grubbs avatar Oct 05 '08 07:10 JC Grubbs
Aceptado

Método estándar ECMAScript 2018

Usarías la extensión de objetos :

let merged = {...obj1, ...obj2};

mergedahora es la unión de obj1y obj2. Las propiedades en obj2sobrescribirá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 obj2que obj1podrí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.

Derek Ziemba avatar Oct 05 '2008 00:10 Derek Ziemba

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.
Avdi avatar Oct 05 '2008 03:10 Avdi

Harmony ECMAScript 2015 (ES6) especifica Object.assigncuá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 .

NanoWizard avatar Oct 05 '2014 19:10 NanoWizard