Frage

Ich muss in der Lage, zwei zu fusionieren (sehr einfach) JavaScript-Objekte zur Laufzeit. Zum Beispiel würde Ich mag an:

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 für diese oder eine in Art und Weise gebaut wissen dies zu tun? Ich habe keine Rekursion benötigen, und ich brauche keine Funktionen zu verschmelzen, nur Methoden, die auf flachen Objekten.

War es hilfreich?

Lösung

ECMAScript 2018 Standardmethode

Sie würden verwenden Objekt Verbreitung :

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

(siehe MDN JavaScript Referenz )


Methode für ES5 und früher

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

Beachten Sie, dass dies einfach alle Attribute obj2 in dem obj1 was vielleicht nicht, was Sie wollen, wenn Sie noch den unveränderten obj1 verwenden mögen.

Wenn Sie einen Rahmen verwenden, die alle über Ihre Prototypen scheißt, dann müssen Sie ausgefallenere mit Kontrollen wie hasOwnProperty zu bekommen, aber das Code für 99% der Fälle arbeiten.

Beispiel Funktion:

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

Andere Tipps

jQuery hat auch ein Programm für diese: http://api.jquery.com/jQuery.extend / .

Genommen von 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 wird das existierende Objekt Namen settings mutieren.


Wenn Sie eine neues Objekt ohne Änderung entweder Argument erstellen möchten, verwenden Sie diese:

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.

Die Harmony ECMAScript 2015 (ES6) Object.assign , die dies tun wird.

Object.assign(obj1, obj2);

Aktuelle Browser-Unterstützung ist immer besser , aber wenn Sie ist für Browser zu entwickeln, die keine Unterstützung haben, können Sie eine polyfill .

I für Code gegoogelt zu Objekteigenschaften zu verschmelzen und hier gelandet. Da jedoch nicht jeder Code für rekursive merge war schrieb ich es selbst. (Vielleicht jQuery erweitern ist rekursiv BTW?) Wie auch immer, hoffentlich jemand anderes wird es nützlich finden auch.

(Jetzt wird der Code nicht Object.prototype verwenden:)

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

Beachten Sie, dass underscore.js 's extend-Methode tut dies in einem Einzeiler:

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

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

Ich brauche, um Objekte heute fusionieren, und diese Frage (und Antworten) hat mir sehr geholfen. Ich habe versucht, einige der Antworten, aber keiner von ihnen meine Bedürfnisse passen, so dass ich einige der Antworten kombiniert, fügte ich etwas und kam mit einer neuen Merge-Funktion auf. Hier ist sie:

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 Beispiele für den Gebrauch:

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

Sie können mit Objekt Ausbreitungseigenschaften -Derzeit eine Stufe 3 ECMAScript Vorschlag.

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

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

Die angegebenen Lösungen modifiziert werden sollen source.hasOwnProperty(property) in den for..in Schleifen, bevor die Zuordnung zu überprüfen - sonst, können Sie die Eigenschaften des gesamten Prototypkette Kopieren am Ende, die nur selten gewünscht wird ...

Merge Eigenschaften von N-Objekten in einer Zeile Code

Eine Object.assign Methode ist Teil des ECMAScript 2015 (ES6) Standard und macht genau das, was Sie brauchen. (IE nicht unterstützt)

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

Die Object.assign () Methode wird verwendet, um die Werte aller enumerable eigenen Eigenschaften von einem oder mehreren Quellobjekte zu einem Zielobjekt zu kopieren.

Lesen Sie mehr ...

Die polyfill ältere Browser unterstützen:

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

Die folgend beide sind wahrscheinlich ein guter Ausgangspunkt. lodash hat auch eine Anpassungsfunktion für die besonderen Bedürfnisse!

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

Ganz nebenbei, was Sie alles tun Eigenschaften überschrieben wird, nicht verschmelzenden ...

Dies ist, wie JavaScript-Objekte Bereich verschmolzen wirklich: Nur Schlüssel in der to Objekt, das nicht-Objekte sind, werden sich durch from überschrieben. Alles andere wird wirklich verschmolzen . Natürlich können Sie dieses Verhalten ändern, um nichts zu überschreiben, die wie nur wenn to[n] is undefined existieren, 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;
};

Verbrauch:

var merged = realMerge(obj1, obj2);

Hier ist mein Stich welche

  1. Unterstützt Deep-Merge
  2. Ist keine Argumente mutieren
  3. nimmt eine beliebige Anzahl von Argumenten
  4. Ist das Objekt Prototyp nicht verlängern
  5. hängt nicht von einer anderen Bibliothek ( jQuery MooTools , Unders Js usw.)
  6. Ist mit Check für hasOwnProperty
  7. ist kurz:)

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

Beispiel:

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)

Dies ist eine neue Technologie, Teil des ECMAScript 2015 (ES6) Standard. Diese Spezifikation Technologie finalisiert wurde, aber für die Nutzung und Umsetzung Status in verschiedenen Browsern die Kompatibilitätstabelle überprüfen.

Die Object.assign () -Methode verwendet, um die Werte aller enumerable eigenen Eigenschaften von einem oder mehreren Quellobjekte zu einem Zielobjekt zu kopieren. Es wird das Zielobjekt zurück.

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.

Für nicht allzu komplizierte Objekte könnten Sie 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_/

Wohlgemerkt, dass in diesem Beispiel "} {" darf nicht auftreten innerhalb eines Strings!

Der beste Weg für Sie, dies zu tun ist, eine richtige Eigenschaft hinzuzufügen, die nicht-zählbare ist Object.defineProperty verwenden.

Auf diese Weise werden Sie noch in der Lage sein, Ihre Objekte Eigenschaften iterieren, ohne dass die neu geschaffenen „erweitern“, das Sie erhalten würden, wenn Sie die Immobilie mit Object.prototype.extend zu schaffen sind.

Hoffentlich hilft:

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

Wenn Sie diese Arbeits haben, können Sie tun:

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

obj.extend(replacement);

Ich habe eine Blog-Post über sie schrieb hier: http: // onemoredigit.com/post/1527191998/extending-objects-in-node-js

Sie können einfach jQuery extend

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

jQuery.extend(obj1, obj2);

Jetzt obj1 enthält alle Werte von obj1 und obj2

Es gibt eine Bibliothek mit dem Namen deepmerge auf GitHub : Das scheint einige Traktion zu bekommen. Es ist ein eigenständiger, verfügbar sowohl durch die npm und Bower Paketmanager.

Ich wäre geneigt, auf diese anstelle von Antworten von kopier Einfügen von Code zu verwenden oder zu verbessern.

Prototype dies hat:

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

obj1.extend(obj2) wird tun, was Sie wollen.

Nur wenn jemand mit Google Closure Bibliothek :

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

ähnliche Hilfsfunktion existiert für Array :

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'

I erweitert David Coallier Methode:

  • Hinzufügen der Möglichkeit, mehrere Objekte zu verschmelzen
  • Unterstützt tiefe Objekte
  • Überschreibung Parameter (das erkannt hat, wenn der letzte Parameter eine boolean)

Wenn Überschreibung falsch ist, wird keine Eigenschaft außer Kraft gesetzt, aber neue Eigenschaften hinzugefügt werden.

Verbrauch: obj.merge (verschmilzt ... [override]);

Hier ist mein Code:

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

Beispiele und Testfälle:

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

Meine Methode equals Sie hier: Objektvergleich in JavaScript

MooTools , gibt es Object.merge () :

Object.merge(obj1, obj2);

Zusammenführen von Objekten ist einfach.

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

Die Objekte von rechts nach links zusammengeführt werden, bedeutet dies, dass Objekte, die identischen Eigenschaften haben wie die Objekte zu ihrem Recht außer Kraft gesetzt werden.

In diesem Beispiel obj2.car Überschreibungen obj1.car

Ext JS 4 es getan werden kann, wie folgt:

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

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

Siehe fusionieren (Objekt):. Objekt

Basierend auf Markus' und Vsync‘beantworten , das ist eine erweiterte Version. Die Funktion nimmt eine beliebige Anzahl von Argumenten. Es kann verwendet werden, um Eigenschaften auf rel="noreferrer"> DOM-Knoten zu setzen und macht tiefe Kopien von Werten. Jedoch wird das erste Argument durch Bezugnahme gegeben.

Um einen DOM-Knoten zu ermitteln, die isDOMNode () Funktion verwendet wird (siehe Frage Stack-Überlauf JavaScript isDOM - How do you überprüfen, ob ein JavaScript-Objekt ein DOM-Objekt ist? )

Es wurde in Opera 11, Firefox 6, Internet Explorer 8 und Google Chrome 16.

Code

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

Einige Beispiele

Set innerHTML- und Stil eines HTML-Elements

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

Merge-Arrays und Objekte. Hinweis, dass nicht definiert zu Preserv Werten in dem linken Array / Objekt verwendet werden.

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

Jedes Argument nicht ein JavaScript-Objekt (einschließlich null) beeing werden ignoriert. Mit Ausnahme des ersten Arguments, DOM auch Knoten verworfen werden. Beachten Sie, dass das heißt Strings, erstellt wie new String () sind in der Tat Objekte.

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

Wenn Sie zwei Objekte in einen neuen verschmelzen (ohne eine der beiden zu beeinflussen) Versorgung {} als erstes Argument

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

Bearbeiten (von ReaperSoon):

Um auch Arrays verschmelzen

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 .. das ist der erste Beitrag habe ich Stackoverflow mit mehreren Seiten gesehen habe. Wir entschuldigen uns für das Hinzufügen eines weiteren „Antwort“

Diese Methode ist für ES5 & Früher - es gibt viele andere Antworten sind Adressierung ES6.

Ich habe keine "tief" Objekt Zusammenlegung der arguments Eigenschaft. Hier ist meine Antwort - compact & rekursive , erlaubt unbegrenzte Objekt Argumente übergeben werden:

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

Der Teil, kommentiert wird aus ist optional .. es einfach Argumente überspringen wird übergeben, die keine Objekte sind (Vermeidung von Fehlern).

Beispiel:

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

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

Diese Antwort ist jetzt nur ein Tropfen auf dem heißen Stein ...

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

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

Mit jQuery.extend () - Link-

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

Mit _.merge () - Link-

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

Mit _.extend () - Link-

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

Mit Object.assign () ECMAScript 2015 (ES6) - Link

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

Ausgabe aller

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

Sie sollten verwenden lodash defaultsDeep

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

Mit Underscore.js , ein Array von Objekten zu fusionieren tun:

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

Es ergibt sich:

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

Es ist erwähnenswert, dass die Version von der 140byt.es Sammlung ist die Aufgabe, auf kleinsten Raum zu lösen und ist einen Versuch wert für diesen Zweck:

Code:

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

Verwendung für Ihren Zweck:

m(obj1,obj2);

Hier ist der original Gist .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top