Frage Wie kann ich Eigenschaften von zwei JavaScript-Objekten dynamisch zusammenführen?


Ich muss in der Lage sein, zwei (sehr einfache) JavaScript-Objekte zur Laufzeit zusammenzuführen. Zum Beispiel möchte ich:

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

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

Hat jemand ein Skript dafür oder weiß von einer eingebauten Möglichkeit das zu tun? Ich brauche keine Rekursion, und ich muss keine Funktionen zusammenführen, nur Methoden für flache Objekte.


1826


Ursprung


Antworten:


ECMAScript 2018 Standardmethode

Du würdest es benutzen Objekt verteilt:

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

ECMAScript 2015 (ES6) Standardmethode

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

(sehen MDN JavaScript-Referenz)


Methode für ES5 und früher

for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }

Beachten Sie, dass hier einfach alle Attribute von hinzugefügt werden obj2 zu obj1 was vielleicht nicht das ist, was du willst, wenn du immer noch das unmodified benutzen willst obj1.

Wenn Sie ein Framework verwenden, das alle Ihre Prototypen scheißt, dann müssen Sie mit Schecks wie zäher werden hasOwnProperty, aber dieser Code wird in 99% der Fälle funktionieren.

Beispielfunktion:

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

1886



jQuery hat auch ein Dienstprogramm dafür: http://api.jquery.com/jQuery.extend/.

Aus der jQuery-Dokumentation:

// 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" }

Der obige Code mutiert die bestehendes Objekt genannt settings.


Wenn Sie einen erstellen möchten neues Objekt ohne eines der beiden Argumente zu ändern, verwende folgendes:

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.

1114



Das Harmony ECMAScript 2015 (ES6) spezifiziert Object.assign was wird das tun.

Object.assign(obj1, obj2);

Aktuelle Browserunterstützung ist besser werden, aber wenn Sie für Browser ohne Unterstützung entwickeln, können Sie a Polyfill.


310



Ich habe nach Code gegoogelt, um Objekteigenschaften zusammenzuführen und bin hier gelandet. Da es jedoch keinen Code für rekursive Zusammenführung gab, habe ich es selbst geschrieben. (Vielleicht ist jQuery extend rekursiv BTW?) Jedenfalls wird hoffentlich auch jemand anderes es nützlich finden.

(Jetzt verwendet der Code nicht Object.prototype :)

Code

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

Ein Beispiel

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

Erzeugt Objekt o3 wie

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

226



Beachten Sie, dass underscore.jsist es extend-Methode macht das in einem One-Liner:

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

166



Ähnlich wie jQuery extend () haben Sie die gleiche Funktion in 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);

80



Ich muss heute Objekte verschmelzen, und diese Frage (und Antworten) hat mir sehr geholfen. Ich habe einige der Antworten ausprobiert, aber keine von ihnen passte zu meinen Bedürfnissen. Daher kombinierte ich einige der Antworten, fügte selbst etwas hinzu und entwickelte eine neue Zusammenführungsfunktion. Hier ist es:

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

Einige Beispielverwendungen:

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

58