Pregunta

Necesito poder combinar 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

¿Alguien tiene una secuencia de comandos para esto o conoce alguna forma integrada de hacerlo? No necesito recursividad, y no necesito combinar funciones, solo métodos en objetos planos.

¿Fue útil?

Solución

Método estándar ECMAScript 2018

Debería utilizar propagación de objetos :

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

/** 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};

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);

(consulte MDN JavaScript Reference )


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 a obj1 que podrían no ser lo que quiere si todavía desea usar el obj1 .

Si está utilizando un marco que cubre todos sus prototipos, entonces tiene que ser más sofisticado con cheques 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;
}

Otros consejos

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 denominado settings .


Si desea crear un nuevo objeto sin modificar ninguno de los argumentos, use 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.

El Harmony ECMAScript 2015 (ES6) especifica Object.assign que hará esto.

Object.assign(obj1, obj2);

El soporte actual del navegador es mejorando , pero si está desarrollando para navegadores que no tienen soporte, puede usar un polyfill .

Busqué en Google el código para combinar las propiedades del objeto y terminé aquí. Sin embargo, como no había ningún código para la combinación recursiva, lo escribí yo mismo. (¿Quizás jQuery extend sea recursivo por cierto?) De todos modos, espero que alguien más también lo encuentre útil.

(Ahora el código no usa Object.prototype :)

Código

/*
* Recursively merge properties of two objects 
*/
function MergeRecursive(obj1, obj2) {

  for (var p in obj2) {
    try {
      // Property in destination object set; update its value.
      if ( obj2[p].constructor==Object ) {
        obj1[p] = MergeRecursive(obj1[p], obj2[p]);

      } else {
        obj1[p] = obj2[p];

      }

    } catch(e) {
      // Property in destination object not set; create it and set its value.
      obj1[p] = obj2[p];

    }
  }

  return obj1;
}

Un ejemplo

o1 = {  a : 1,
        b : 2,
        c : {
          ca : 1,
          cb : 2,
          cc : {
            cca : 100,
            ccb : 200 } } };

o2 = {  a : 10,
        c : {
          ca : 10,
          cb : 20, 
          cc : {
            cca : 101,
            ccb : 202 } } };

o3 = MergeRecursive(o1, o2);

Produce un objeto o3 como

o3 = {  a : 10,
        b : 2,
        c : {
          ca : 10,
          cb : 20,
          cc : { 
            cca : 101,
            ccb : 202 } } };

Tenga en cuenta que underscore.js 's extend -method hace esto en una sola línea:

_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}

Similar a jQuery extend (), tiene la misma función en AngularJS :

// Merge the 'options' object into the 'settings' object
var settings = {validate: false, limit: 5, name: "foo"};
var options  = {validate: true, name: "bar"};
angular.extend(settings, options);

Necesito fusionar objetos hoy, y esta pregunta (y respuestas) me ayudó mucho. Probé algunas de las respuestas, pero ninguna de ellas se ajustó a mis necesidades, así que combiné algunas de las respuestas, agregué algo por mi cuenta y se me ocurrió una nueva función de combinación. Aquí está:

var merge = function() {
    var obj = {},
        i = 0,
        il = arguments.length,
        key;
    for (; i < il; i++) {
        for (key in arguments[i]) {
            if (arguments[i].hasOwnProperty(key)) {
                obj[key] = arguments[i][key];
            }
        }
    }
    return obj;
};

Algunos usos de ejemplo:

var t1 = {
    key1: 1,
    key2: "test",
    key3: [5, 2, 76, 21]
};
var t2 = {
    key1: {
        ik1: "hello",
        ik2: "world",
        ik3: 3
    }
};
var t3 = {
    key2: 3,
    key3: {
        t1: 1,
        t2: 2,
        t3: {
            a1: 1,
            a2: 3,
            a4: [21, 3, 42, "asd"]
        }
    }
};

console.log(merge(t1, t2));
console.log(merge(t1, t3));
console.log(merge(t2, t3));
console.log(merge(t1, t2, t3));
console.log(merge({}, t1, { key1: 1 }));

Puede utilizar propiedades de propagación de objetos y # 8212; actualmente es una propuesta ECMAScript de la etapa 3 .

const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };

const obj3 = { ...obj1, ...obj2 };
console.log(obj3);

Las soluciones dadas deben modificarse para verificar source.hasOwnProperty (propiedad) en los for..in antes de asignar; de lo contrario, terminará copiando las propiedades de Toda la cadena de prototipos, que rara vez se desea ...

Fusionar propiedades de N objetos en una línea de código

Un método

Object.assign es parte del estándar ECMAScript 2015 (ES6) y hace exactamente lo que necesita. ( IE no es compatible)

var clone = Object.assign({}, obj);
  

El método Object.assign () se usa para copiar los valores de todas las propiedades propias enumerables de uno o más objetos de origen a un objeto de destino.

Leer más ...

El polyfill para admitir navegadores más antiguos:

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

Los dos siguientes son probablemente un buen punto de partida. ¡lodash también tiene una función de personalización para esas necesidades especiales!

_.extend ( http://underscorejs.org/#extend )
_.merge ( https://lodash.com/docs#merge )

Por cierto, lo que está haciendo es sobrescribir las propiedades, no fusionar ...

Así es como el área de objetos JavaScript realmente se fusionó: solo las claves en el objeto to que no son objetos en sí mismas serán sobrescritas por from . Todo lo demás será realmente fusionado . Por supuesto, puede cambiar este comportamiento para que no sobrescriba nada que exista como solo si a [n] no está definido , etc ...:

var realMerge = function (to, from) {

    for (n in from) {

        if (typeof to[n] != 'object') {
            to[n] = from[n];
        } else if (typeof from[n] == 'object') {
            to[n] = realMerge(to[n], from[n]);
        }
    }
    return to;
};

Uso:

var merged = realMerge(obj1, obj2);

Aquí está mi puñalada que

  1. Soporta fusión profunda
  2. No muta argumentos
  3. toma cualquier cantidad de argumentos
  4. No extiende el prototipo de objeto
  5. No depende de otra biblioteca ( jQuery , MooTools , Subrayado .js , etc.)
  6. Incluye cheque para hasOwnProperty
  7. Es corto :)

    /*
        Recursively merge properties and return new object
        obj1 &lt;- obj2 [ &lt;- ... ]
    */
    function merge () {
        var dst = {}
            ,src
            ,p
            ,args = [].splice.call(arguments, 0)
        ;
    
        while (args.length > 0) {
            src = args.splice(0, 1)[0];
            if (toString.call(src) == '[object Object]') {
                for (p in src) {
                    if (src.hasOwnProperty(p)) {
                        if (toString.call(src[p]) == '[object Object]') {
                            dst[p] = merge(dst[p] || {}, src[p]);
                        } else {
                            dst[p] = src[p];
                        }
                    }
                }
            }
        }
    
       return dst;
    }
    

Ejemplo:

a = {
    "p1": "p1a",
    "p2": [
        "a",
        "b",
        "c"
    ],
    "p3": true,
    "p5": null,
    "p6": {
        "p61": "p61a",
        "p62": "p62a",
        "p63": [
            "aa",
            "bb",
            "cc"
        ],
        "p64": {
            "p641": "p641a"
        }
    }
};

b = {
    "p1": "p1b",
    "p2": [
        "d",
        "e",
        "f"
    ],
    "p3": false,
    "p4": true,
    "p6": {
        "p61": "p61b",
        "p64": {
            "p642": "p642b"
        }
    }
};

c = {
    "p1": "p1c",
    "p3": null,
    "p6": {
        "p62": "p62c",
        "p64": {
            "p643": "p641c"
        }
    }
};

d = merge(a, b, c);


/*
    d = {
        "p1": "p1c",
        "p2": [
            "d",
            "e",
            "f"
        ],
        "p3": null,
        "p5": null,
        "p6": {
            "p61": "p61b",
            "p62": "p62c",
            "p63": [
                "aa",
                "bb",
                "cc"
            ],
            "p64": {
                "p641": "p641a",
                "p642": "p642b",
                "p643": "p641c"
            }
        },
        "p4": true
    };
*/

Object.assign()

ECMAScript 2015 (ES6)

Esta es una nueva tecnología, parte del estándar ECMAScript 2015 (ES6). La especificación de esta tecnología se ha finalizado, pero consulte la tabla de compatibilidad para ver el uso y el estado de implementación en varios navegadores.

El método Object.assign () se usa para copiar los valores de todas las propiedades propias enumerables de uno o más objetos de origen a un objeto de destino. Devolverá el objeto objetivo.

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.

Para objetos no demasiado complicados, puede usar JSON :

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'chevy'}
var objMerge;

objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);

// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}

objMerge = objMerge.replace(/\}\{/, ","); //  \_ replace with comma for valid JSON

objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/

Te importa que en este ejemplo "} {" no debe aparecer dentro de una cadena

La mejor manera de hacer esto es agregar una propiedad adecuada que no sea enumerable usando Object.defineProperty.

De esta manera, aún podrá recorrer las propiedades de sus objetos sin tener el nuevo " ampliado " que obtendría si tuviera que crear la propiedad con Object.prototype.extend.

Esperemos que esto ayude:

Object.defineProperty(Object.prototype, "extend", {
    enumerable: false,
    value: function(from) {
        var props = Object.getOwnPropertyNames(from);
        var dest = this;
        props.forEach(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});

Una vez que lo tienes funcionando, puedes hacerlo:

var obj = {
    name: 'stack',
    finish: 'overflow'
}
var replacement = {
    name: 'stock'
};

obj.extend(replacement);

Acabo de escribir una entrada de blog al respecto aquí: http: // onemoredigit.com/post/1527191998/extending-objects-in-node-js

Simplemente puedes usar jQuery extend

var obj1 = { val1: false, limit: 5, name: "foo" };
var obj2 = { val2: true, name: "bar" };

jQuery.extend(obj1, obj2);

Ahora obj1 contiene todos los valores de obj1 y obj2

Hay una biblioteca llamada deepmerge en GitHub : Eso parece estar recibiendo algo de tracción. Es independiente, disponible a través de npm y los administradores de paquetes de Bower.

Me inclinaría por usar o mejorar esto en lugar de copiar y pegar código de las respuestas.

Prototype tiene esto:

Object.extend = function(destination,source) {
    for (var property in source)
        destination[property] = source[property];
    return destination;
}

obj1.extend (obj2) hará lo que quieras.

Solo si alguien está usando Biblioteca de cierres de Google :

goog.require('goog.object');
var a = {'a': 1, 'b': 2};
var b = {'b': 3, 'c': 4};
goog.object.extend(a, b);
// Now object a == {'a': 1, 'b': 3, 'c': 4};

Existe una función de ayuda similar para la matriz :

var a = [1, 2];
var b = [3, 4];
goog.array.extend(a, b); // Extends array 'a'
goog.array.concat(a, b); // Returns concatenation of array 'a' and 'b'

Extendí el método de David Coallier:

  • Se agregó la posibilidad de fusionar varios objetos
  • Admite objetos profundos
  • parámetro de anulación (que se detecta si el último parámetro es booleano)

Si la anulación es falsa, ninguna propiedad se anula, pero se agregarán nuevas propiedades.

Uso: obj.merge (fusiona ... [, anular])

Aquí está mi código:

Object.defineProperty(Object.prototype, "merge", {
    enumerable: false,
    value: function () {
        var override = true,
            dest = this,
            len = arguments.length,
            props, merge, i, from;

        if (typeof(arguments[arguments.length - 1]) === "boolean") {
            override = arguments[arguments.length - 1];
            len = arguments.length - 1;
        }

        for (i = 0; i < len; i++) {
            from = arguments[i];
            if (from != null) {
                Object.getOwnPropertyNames(from).forEach(function (name) {
                    var descriptor;

                    // nesting
                    if ((typeof(dest[name]) === "object" || typeof(dest[name]) === "undefined")
                            && typeof(from[name]) === "object") {

                        // ensure proper types (Array rsp Object)
                        if (typeof(dest[name]) === "undefined") {
                            dest[name] = Array.isArray(from[name]) ? [] : {};
                        }
                        if (override) {
                            if (!Array.isArray(dest[name]) && Array.isArray(from[name])) {
                                dest[name] = [];
                            }
                            else if (Array.isArray(dest[name]) && !Array.isArray(from[name])) {
                                dest[name] = {};
                            }
                        }
                        dest[name].merge(from[name], override);
                    } 

                    // flat properties
                    else if ((name in dest && override) || !(name in dest)) {
                        descriptor = Object.getOwnPropertyDescriptor(from, name);
                        if (descriptor.configurable) {
                            Object.defineProperty(dest, name, descriptor);
                        }
                    }
                });
            }
        }
        return this;
    }
});

Ejemplos y TestCases:

function clone (obj) {
    return JSON.parse(JSON.stringify(obj));
}
var obj = {
    name : "trick",
    value : "value"
};

var mergeObj = {
    name : "truck",
    value2 : "value2"
};

var mergeObj2 = {
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
};

assertTrue("Standard", clone(obj).merge(mergeObj).equals({
    name : "truck",
    value : "value",
    value2 : "value2"
}));

assertTrue("Standard no Override", clone(obj).merge(mergeObj, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2"
}));

assertTrue("Multiple", clone(obj).merge(mergeObj, mergeObj2).equals({
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
}));

assertTrue("Multiple no Override", clone(obj).merge(mergeObj, mergeObj2, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2",
    value3 : "value3"
}));

var deep = {
    first : {
        name : "trick",
        val : "value"
    },
    second : {
        foo : "bar"
    }
};

var deepMerge = {
    first : {
        name : "track",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
};

assertTrue("Deep merges", clone(deep).merge(deepMerge).equals({
    first : {
        name : "track",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
}));

assertTrue("Deep merges no override", clone(deep).merge(deepMerge, false).equals({
    first : {
        name : "trick",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "bar",
        bar : "bam"
    },
    v : "on first layer"
}));

var obj1 = {a: 1, b: "hello"};
obj1.merge({c: 3});
assertTrue(obj1.equals({a: 1, b: "hello", c: 3}));

obj1.merge({a: 2, b: "mom", d: "new property"}, false);
assertTrue(obj1.equals({a: 1, b: "hello", c: 3, d: "new property"}));

var obj2 = {};
obj2.merge({a: 1}, {b: 2}, {a: 3});
assertTrue(obj2.equals({a: 3, b: 2}));

var a = [];
var b = [1, [2, 3], 4];
a.merge(b);
assertEquals(1, a[0]);
assertEquals([2, 3], a[1]);
assertEquals(4, a[2]);


var o1 = {};
var o2 = {a: 1, b: {c: 2}};
var o3 = {d: 3};
o1.merge(o2, o3);
assertTrue(o1.equals({a: 1, b: {c: 2}, d: 3}));
o1.b.c = 99;
assertTrue(o2.equals({a: 1, b: {c: 2}}));

// checking types with arrays and objects
var bo;
a = [];
bo = [1, {0:2, 1:3}, 4];
b = [1, [2, 3], 4];

a.merge(b);
assertTrue("Array stays Array?", Array.isArray(a[1]));

a = [];
a.merge(bo);
assertTrue("Object stays Object?", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo);
assertTrue("Object overrides Array", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo, false);
assertTrue("Object does not override Array", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b);
assertTrue("Array overrides Object", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b, false);
assertTrue("Array does not override Object", !Array.isArray(a[1]));

Mi método de igualdad se puede encontrar aquí: Comparación de objetos en JavaScript

En MooTools , hay Object.merge () :

Object.merge(obj1, obj2);

Fusionar objetos es simple.

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'BMW' }
var obj3 = {a: "A"}


var mergedObj = Object.assign(obj1,obj2,obj3)

console.log(mergedObj);

Los objetos se combinan de derecha a izquierda, esto significa que los objetos que tienen propiedades idénticas a los objetos a su derecha serán anulados.

En este ejemplo, obj2.car anula obj1.car

En Ext & nbsp; JS 4 se puede hacer de la siguiente manera:

var mergedObject = Ext.Object.merge(object1, object2)

// Or shorter:
var mergedObject2 = Ext.merge(object1, object2)

Ver fusionar (objeto): Objeto .

Basado en Markus ' y vsync 'answer , esta es una versión expandida. La función toma cualquier número de argumentos. Se puede usar para establecer propiedades en los nodos DOM y realiza copias en profundidad de los valores. Sin embargo, el primer argumento se da por referencia.

Para detectar un nodo DOM, se utiliza la función isDOMNode () (consulte la pregunta sobre el desbordamiento de Pila JavaScript isDOM - ¿Cómo ¿Comprueba si un objeto JavaScript es un objeto DOM? )

Se probó en Opera 11, Firefox 6, Internet & nbsp; Explorer & nbsp; 8 y Google Chrome 16.

Código

function mergeRecursive() {

  // _mergeRecursive does the actual job with two arguments.
  var _mergeRecursive = function (dst, src) {
    if (isDOMNode(src) || typeof src !== 'object' || src === null) {
      return dst;
    }

    for (var p in src) {
      if (!src.hasOwnProperty(p))
        continue;
      if (src[p] === undefined)
        continue;
      if ( typeof src[p] !== 'object' || src[p] === null) {
        dst[p] = src[p];
      } else if (typeof dst[p]!=='object' || dst[p] === null) {
        dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]);
      } else {
        _mergeRecursive(dst[p], src[p]);
      }
    }
    return dst;
  }

  // Loop through arguments and merge them into the first argument.
  var out = arguments[0];
  if (typeof out !== 'object' || out === null)
    return out;
  for (var i = 1, il = arguments.length; i < il; i++) {
    _mergeRecursive(out, arguments[i]);
  }
  return out;
}

Algunos ejemplos

Establecer innerHTML y el estilo de un elemento HTML

mergeRecursive(
  document.getElementById('mydiv'),
  {style: {border: '5px solid green', color: 'red'}},
  {innerHTML: 'Hello world!'});

Combinar matrices y objetos. Tenga en cuenta que undefined se puede usar para preservar los valores en la matriz / objeto de la izquierda.

o = mergeRecursive({a:'a'}, [1,2,3], [undefined, null, [30,31]], {a:undefined, b:'b'});
// o = {0:1, 1:null, 2:[30,31], a:'a', b:'b'}

Cualquier argumento que no sea un objeto JavaScript (incluido el valor nulo) se ignorará. Excepto por el primer argumento, también se descartan los nodos DOM. Tenga en cuenta que, por ejemplo, las cadenas, creadas como nuevas String () son en realidad objetos.

o = mergeRecursive({a:'a'}, 1, true, null, undefined, [1,2,3], 'bc', new String('de'));
// o = {0:'d', 1:'e', 2:3, a:'a'}

Si desea combinar dos objetos en un nuevo suministro (sin afectar a ninguno de los dos) {} como primer argumento

var a={}, b={b:'abc'}, c={c:'cde'}, o;
o = mergeRecursive(a, b, c);
// o===a is true, o===b is false, o===c is false

Editar (por ReaperSoon):

Para también combinar matrices

function mergeRecursive(obj1, obj2) {
  if (Array.isArray(obj2)) { return obj1.concat(obj2); }
  for (var p in obj2) {
    try {
      // Property in destination object set; update its value.
      if ( obj2[p].constructor==Object ) {
        obj1[p] = mergeRecursive(obj1[p], obj2[p]);
      } else if (Array.isArray(obj2[p])) {
        obj1[p] = obj1[p].concat(obj2[p]);
      } else {
        obj1[p] = obj2[p];
      }
    } catch(e) {
      // Property in destination object not set; create it and set its value.
      obj1[p] = obj2[p];
    }
  }
  return obj1;
}

Wow ... esta es la primera publicación de StackOverflow que he visto con varias páginas. Disculpas por agregar otra " respuesta "

Este método es para ES5 & amp; Anteriormente : hay muchas otras respuestas relacionadas con ES6.

No vi ningún objeto " deep " combinando utilizando el argumentos . Aquí está mi respuesta: compacto & amp; recursivo , que permite pasar argumentos de objeto ilimitados:

function extend() {
    for (var o = {}, i = 0; i < arguments.length; i++) {
        // if (arguments[i].constructor !== Object) continue;
        for (var k in arguments[i]) {
            if (arguments[i].hasOwnProperty(k)) {
                o[k] = arguments[i][k].constructor === Object ? extend(o[k] || {}, arguments[i][k]) : arguments[i][k];
            }
        }
    }
    return o;
}

La parte que se comenta es opcional ... simplemente omitirá los argumentos pasados ??que no sean objetos (evitando errores).

Ejemplo :

extend({
    api: 1,
    params: {
        query: 'hello'
    }
}, {
    params: {
        query: 'there'
    }
});

// outputs {api: 1, params: {query: 'there'}}
  

Esta respuesta es ahora solo una gota en el océano ...

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

// result
result: {food: "pizza", car: "ford", animal: "dog"}

Utilizando jQuery.extend () - Enlace

// Merge obj1 & obj2 to result
var result1 = $.extend( {}, obj1, obj2 );

Utilizando _.merge () - Enlace

// Merge obj1 & obj2 to result
var result2 = _.merge( {}, obj1, obj2 );

Utilizando _.extend () - Enlace

// Merge obj1 & obj2 to result
var result3 = _.extend( {}, obj1, obj2 );

Usando Object.assign () ECMAScript 2015 (ES6) - Enlace

// Merge obj1 & obj2 to result
var result4 = Object.assign( {}, obj1, obj2 );

Salida de todos

obj1: { animal: 'dog' }
obj2: { food: 'pizza', car: 'ford' }
result1: {food: "pizza", car: "ford", animal: "dog"}
result2: {food: "pizza", car: "ford", animal: "dog"}
result3: {food: "pizza", car: "ford", animal: "dog"}
result4: {food: "pizza", car: "ford", animal: "dog"}

Debería utilizar defaultsDeep de lodash

_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
// → { 'user': { 'name': 'barney', 'age': 36 } }

Con Underscore.js , para fusionar una serie de objetos:

var arrayOfObjects = [ {a:1}, {b:2, c:3}, {d:4} ];
_(arrayOfObjects).reduce(function(memo, o) { return _(memo).extend(o); });

Da como resultado:

Object {a: 1, b: 2, c: 3, d: 4}

Vale la pena mencionar que la versión de la colección 140byt.es está resolviendo la tarea en un espacio mínimo y es Vale la pena intentarlo para este propósito:

Código:

function m(a,b,c){for(c in b)b.hasOwnProperty(c)&&((typeof a[c])[0]=='o'?m(a[c],b[c]):a[c]=b[c])}

Uso para su propósito:

m(obj1,obj2);

Aquí está la Gist original .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top