it-swarm.com.de

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

Ich muss zwei (sehr einfache) JavaScript-Objekte zur Laufzeit zusammenführen können. 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 kennt einen eingebauten Weg, um dies zu tun? Ich brauche keine Rekursion und ich muss keine Funktionen zusammenführen, sondern nur Methoden für flache Objekte.

2072
JC Grubbs

ECMAScript 2018 Standardmethode

Sie würden object spread verwenden:

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ühere

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

Beachten Sie, dass dies einfach alle Attribute von obj2 zu obj1 hinzufügt. Dies ist möglicherweise nicht das, was Sie möchten, wenn Sie trotzdem den unveränderten obj1 verwenden möchten.

Wenn Sie ein Framework verwenden, das Ihre gesamten Prototypen überfüllt, müssen Sie mit Prüfungen wie hasOwnProperty etwas ausgefallener sein, aber der Code funktioniert in 99% der Fälle.

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;
}
2312
John Millikin

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

Aus der jQuery-Dokumentation entnommen:

// 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 verändert das vorhandenes Objekt mit dem Namen settings.


Wenn Sie ein neues Objekt erstellen möchten, ohne eines der Argumente zu ändern, verwenden Sie 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.
1149
Avdi

Das Harmony ECMAScript 2015 (ES6) gibt Object.assign an, das dies tut.

Object.assign(obj1, obj2);

Die aktuelle Browserunterstützung ist wird besser , aber wenn Sie für Browser entwickeln, die keine Unterstützung bieten, können Sie Polyfill verwenden.

323
NanoWizard

Ich googelte nach Code, um die Objekteigenschaften zusammenzuführen, und landete hier. Da es jedoch keinen Code für die rekursive Zusammenführung gab, habe ich ihn selbst geschrieben. (Vielleicht ist jQuery extend rekursiv?) Hoffentlich findet es auch jemand anderes nützlich.

(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 das Objekt o3 wie

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

Beachten Sie, dass underscore.js 's extend- method dies in einem Einzeiler ausführt:

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

Ähnlich wie bei jQuery extend () haben Sie dieselbe 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);
84
AndreasE

Ich muss heute Objekte zusammenführen, und diese Frage (und Antworten) hat mir sehr geholfen. Ich habe einige der Antworten ausprobiert, aber keine davon entsprach 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 beispielhafte Verwendungen:

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 }));
63
Emre Erkan

Sie können object spread properties verwenden - derzeit einen ECMAScript-Vorschlag der Stufe 3.

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

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

46
Jaime Asm

Die angegebenen Lösungen sollten modifiziert werden, um source.hasOwnProperty(property) in den for..in-Schleifen zu prüfen, bevor Sie sie zuweisen. Andernfalls kopieren Sie die Eigenschaften der gesamten Prototypkette, was selten erwünscht ist ...

39
Christoph

Eigenschaften von N Objekten in einer Codezeile zusammenführen

Eine Object.assign-Methode ist Teil des Standards ECMAScript 2015 (ES6) und erfüllt genau das, was Sie brauchen. (IE wird nicht unterstützt)

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

Die Object.assign () -Methode wird verwendet, um die Werte aller aufzählbaren eigenen Eigenschaften von einem oder mehreren Quellobjekten in ein Zielobjekt zu kopieren.

Weiterlesen...

Die polyfill zur Unterstützung älterer Browser:

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;
    }
  });
}
37
Eugene Tiurin

Die folgenden zwei sind wahrscheinlich ein guter Ausgangspunkt. lodash hat auch eine anpassungsfunktion für besondere anforderungen!

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

31
appsmatics

Übrigens: Alles was Sie tun, ist das Überschreiben von Eigenschaften, nicht das Zusammenführen ...

So wurde der Bereich der JavaScript-Objekte wirklich zusammengeführt: Nur Schlüssel im Objekt to, die selbst keine Objekte sind, werden von from überschrieben. Alles andere wirdwirklich zusammengeführt. Natürlich können Sie dieses Verhalten ändern, um nichts zu überschreiben, das nur dann existiert, wenn to[n] is undefined usw.:

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

Verwendungszweck:

var merged = realMerge(obj1, obj2);
23
Andreas Linden

Hier ist mein Stich was

  1. Unterstützt tiefes Zusammenführen
  2. Argumente nicht mutieren
  3. Beliebig viele Argumente
  4. Erweitert den Objektprototyp nicht
  5. Hängt nicht von einer anderen Bibliothek ab ( jQuery , MooTools , Underscore.js usw.)
  6. Enthält die Prüfung auf 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
    };
*/
21
Paul Spaulding

Object.assign ()

ECMAScript 2015 (ES6)

Dies ist eine neue Technologie, Teil des Standards ECMAScript 2015 (ES6) ..__: Die Spezifikation dieser Technologie wurde abgeschlossen, aber überprüfen Sie die Kompatibilitätstabelle in verschiedenen Browsern auf Verwendung und Implementierungsstatus.

Die Object.assign () -Methode wird verwendet, um die Werte aller aufzählbaren eigenen Eigenschaften von einem oder mehreren Quellobjekten in ein Zielobjekt zu kopieren. Das Zielobjekt wird zurückgegeben.

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.
17
Reza Roshan

Für nicht zu komplizierte Objekte können Sie JSON verwenden:

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_/

Beachten Sie, dass in diesem Beispiel "} {" darf nicht vorkommen innerhalb einer Zeichenfolge!

17
Algy

Am besten fügen Sie dazu eine geeignete Eigenschaft hinzu, die mit Object.defineProperty nicht aufgezählt werden kann. 

Auf diese Weise können Sie weiterhin die Eigenschaften Ihrer Objekte durchlaufen, ohne das neu erstellte "extend" zu erhalten, das Sie erhalten würden, wenn Sie die Eigenschaft mit Object.prototype.extend erstellen würden.

Hoffentlich hilft das:

 Object.defineProperty (Object.prototype, "extend", {
 Enumerable: false, 
 Value: function (from) {
 Var props = Object.getOwnPropertyNames (from); 
 Var dest = this; 
 props.forEach (Funktion (name) {
 if (name in dest) {
 var destination = Object.getOwnPropertyDescriptor (von, name); 
 Object.defineProperty (dest, Name, Ziel); 
} 
}); 
 zurückgeben; 
} 
}); 

Sobald Sie diese Arbeit haben, können Sie Folgendes tun:

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

 obj.extend (Ersetzung); 

Ich habe gerade einen Blogbeitrag hier geschrieben: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js

15
David Coallier

Sie können einfach jQueryextendverwenden.

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

jQuery.extend(obj1, obj2);

Nun enthält obj1 alle Werte von obj1 und obj2

14
Dinusha

Es gibt eine Bibliothek namens deepmerge on GitHub : Das scheint etwas Traktion zu bekommen. Es ist ein eigenständiges System, das über die Paketmanager npm und Bower verfügbar ist.

Ich wäre geneigt, dies zu verwenden oder zu verbessern, anstatt Code aus Antworten zu kopieren.

14
antitoxic

Prototyp hat folgendes:

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

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

11
ephemient

Nur wenn jemand Google Closure Library verwendet:

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 für Array vorhanden :

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'
10
Paweł Szczur

Ich habe die Methode von David Coallier erweitert:

  • Möglichkeit hinzugefügt, mehrere Objekte zusammenzuführen
  • Unterstützt tiefe Objekte
  • Überschreibungsparameter (wird erkannt, wenn der letzte Parameter ein Boolean ist)

Wenn Überschreiben falsch ist, wird keine Eigenschaft überschrieben, aber neue Eigenschaften werden hinzugefügt.

Verwendung: Obj.merge (merges ... [ 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 equals-Methode finden Sie hier: Objektvergleich in JavaScript

8
gossi

In MooTools gibt es Object.merge () :

Object.merge(obj1, obj2);
8
philfreo

Das 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 werden von rechts nach links zusammengefügt. Dies bedeutet, dass Objekte mit identischen Eigenschaften wie die Objekte auf der rechten Seite überschrieben werden.

In diesem Beispiel überschreibt obj2.carobj1.car

8
Legends

Basierend auf Markus ' und vsync' ist dies eine erweiterte Version. Die Funktion akzeptiert eine beliebige Anzahl von Argumenten. Es kann verwendet werden, um Eigenschaften für DOM Knoten festzulegen und tiefe Kopien von Werten zu erstellen. Das erste Argument wird jedoch durch Bezugnahme gegeben.

Zum Erkennen eines DOM-Knotens wird die Funktion isDOMNode () verwendet (siehe Frage zum Stapelüberlauf JavaScript isDOM - Wie prüft man, ob ein JavaScript-Objekt ein DOM-Objekt ist?)

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

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

Legt innerHTML und den Stil eines HTML-Elements fest

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

Arrays und Objekte zusammenführen. Beachten Sie, dass undefined verwendet werden kann, um Werte im linken Array/Objekt beizubehalten.

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, das kein JavaScript-Objekt ist (einschließlich null), wird ignoriert. Mit Ausnahme des ersten Arguments werden auch DOM-Knoten verworfen. Beachten Sie, dass es sich bei Strings, die wie new String () erstellt wurden, tatsächlich um Objekte handelt.

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 zu einem neuen zusammenführen möchten (ohne einen der beiden zu beeinflussen), geben Sie {} als erstes Argument an

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

Arrays zusammenführen

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

In Ext JS 4 kann dies wie folgt durchgeführt werden:

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

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

Siehe merge (object): Object.

7
Mark

Wow ... das ist der erste StackOverflow-Beitrag, den ich mit mehreren Seiten gesehen habe. Entschuldigung für das Hinzufügen einer weiteren "Antwort"

Diese Methode ist für ES5 & früher - es gibt viele andere Antworten, die sich an ES6 richten. 

Ich habe kein "deep"-Objekt gesehen, das unter Verwendung der arguments - Eigenschaft zusammengeführt wurde. Hier ist meine Antwort - compact & rekursiv, die die Übergabe uneingeschränkter Objektargumente erlaubt:

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 auskommentierte Teil ist optional. Er überspringt einfach übergebene Argumente, die keine Objekte sind (verhindert Fehler). 

Beispiel:

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

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

Diese Antwort ist jetzt nur ein Tropfen im Ozean ...

6
Logan

Mit Underscore.js können Sie ein Array von Objekten zusammenführen:

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

Es fuehrt zu:

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

Es ist erwähnenswert, dass die Version aus der Sammlung 140byt.es die Aufgabe auf kleinstem Raum löst und zu diesem Zweck einen Versuch wert ist:

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 das Original Gist .

4
pagid

Sie sollten lodash's defaultsDeep verwenden.

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

Ich benutze das Folgende, was in reinem JavaScript ist. Sie beginnt mit dem Argument ganz rechts und kombiniert sie bis zum ersten Argument. Es gibt keinen Rückgabewert, nur das erste Argument wird geändert und der Parameter ganz links (außer dem ersten) hat die höchste Gewichtung der Eigenschaften.

var merge = function() {
  var il = arguments.length;

  for (var i = il - 1; i > 0; --i) {
    for (var key in arguments[i]) {
      if (arguments[i].hasOwnProperty(key)) {
        arguments[0][key] = arguments[i][key];
      }
    }
  }
};
3
Etherealone
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

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

Verwenden von jQuery.extend () - Link

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

Verwenden von _.merge () - Link

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

Verwenden von _.extend () - Link

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

Verwenden von Object.assign () ECMAScript 2015 (ES6) - Link

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

Ausgabe von allen

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

ES2018/TypeScript: Viele Antworten sind in Ordnung, aber ich habe eine elegantere Lösung für dieses Problem gefunden, wenn Sie zwei Objekte zusammenführen müssen ohne überlappende Objektschlüssel zu überschreiben .

Meine Funktion akzeptiert auch unbegrenzte Anzahl von Objekten zum Zusammenführen als Funktionsargumente:

(Ich verwende hier die TypeScript-Notation. Wenn Sie einfaches JavaScript verwenden, können Sie den Typ :object[] im Funktionsargument löschen.)

const merge = (...objects: object[]) => {
  return objects.reduce((prev, next) => {
    Object.keys(prev).forEach(key => {
      next[key] = { ...next[key], ...prev[key] }
    })
    return next
  })
}
2
Paweł Otto

function extend(o, o1, o2){
    if( !(o instanceof Object) ) o = {};

    copy(o, o1);
    if( o2 )
        copy(o, o2)

    function isObject(obj) {
        var type = Object.prototype.toString.call(obj);
        return obj === Object(obj) && type != '[object Array]' && type != '[object Function]';
    };

    function copy(a,b){
        // copy o2 to o
        for( var key in b )
            if( b.hasOwnProperty(key) ){
                if( isObject(b[key]) ){
                    if( !isObject(a[key]) )
                        a[key] = Object.assign({}, b[key]); 
                    else copy(a[key], b[key])
                }
                else
                    a[key] = b[key];
            }
    }

    return o;
};


var o1 = {a:{foo:1}, b:1},
    o2 = {a:{bar:2}, b:[1], c:()=>{}},
    newMerged = extend({}, o1, o2);
    
console.log( newMerged )
console.log( o1 )
console.log( o2 )

2
vsync

gossis Erweiterung der Methode von David Coallier:

Überprüfen Sie diese beiden Zeilen:

from = arguments[i];
Object.getOwnPropertyNames(from).forEach(function (name) {

Man muss "from" gegen ein Nullobjekt prüfen ... Wenn zum Beispiel ein Objekt, das aus einer Ajax - Antwort stammt, die zuvor auf einem Server erstellt wurde, zusammengeführt wird, kann eine Objekteigenschaft den Wert "null" und in haben In diesem Fall generiert der obige Code eine Fehlermeldung mit der folgenden Angabe:

"from" ist kein gültiges Objekt

Wenn Sie beispielsweise die Funktion "... Object.getOwnPropertyNames (from) .forEach ..." mit "if (from! = Null) {...}" umschließen, wird das Auftreten dieses Fehlers verhindert.

2
user909278

Benutzen:

//Takes any number of objects and returns one merged object
var objectMerge = function(){
    var out = {};
    if(!arguments.length)
        return out;
    for(var i=0; i<arguments.length; i++) {
        for(var key in arguments[i]){
            out[key] = arguments[i][key];
        }
    }
    return out;
}

Es wurde getestet mit:

console.log(objectMerge({a:1, b:2}, {a:2, c:4}));

Es fuehrt zu:

{ a: 2, b: 2, c: 4 }
2
RobKohr

Auf meine Art:

function mergeObjects(defaults, settings) {
    Object.keys(defaults).forEach(function(key_default) {
        if (typeof settings[key_default] == "undefined") {
            settings[key_default] = defaults[key_default];
        } else if (isObject(defaults[key_default]) && isObject(settings[key_default])) {
            mergeObjects(defaults[key_default], settings[key_default]);
        }
    });

    function isObject(object) {
        return Object.prototype.toString.call(object) === '[object Object]';
    }

    return settings;
}

:)

2
bravedick

Hier, was ich in meiner Codebase zum Zusammenführen verwendet habe.

function merge(to, from) {
  if (typeof to === 'object' && typeof from === 'object') {
    for (var pro in from) {
      if (from.hasOwnProperty(pro)) {
        to[pro] = from[pro];
      }
    }
  }
  else{
      throw "Merge function can apply only on object";
  }
}
1
Nishant Kumar

Ich fange mit JavaScript an, also korrigiere mich, falls ich falsch liege.

Aber wäre es nicht besser, wenn Sie eine beliebige Anzahl von Objekten zusammenführen könnten? So mache ich es mit dem nativen Arguments-Objekt.

Der Schlüssel dazu ist, dass Sie tatsächlich eine beliebige Anzahl von Argumenten an eine JavaScript-Funktion übergeben können, ohne sie in der Funktionsdeklaration zu definieren. Sie können einfach nicht auf sie zugreifen, ohne das Arguments-Objekt zu verwenden.

function mergeObjects() (
    var tmpObj = {};

    for(var o in arguments) {
        for(var m in arguments[o]) {
            tmpObj[m] = arguments[o][m];
        }
    }
    return tmpObj;
}
1
antony

In YUIY.merge soll die Arbeit erledigt sein:

Y.merge(obj1, obj2, obj3....) 
1
Prabhakar Kasi

Die korrekte Implementierung in Prototype sollte folgendermaßen aussehen:

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

obj1 = Object.extend(obj1, obj2);
1
Tobi

Für diejenigen, die Node.js verwenden, gibt es ein NPM-Modul: node.extend

Installieren:

npm install node.extend

Verwendungszweck:

var extend = require('node.extend');
var destObject = extend(true, {}, sourceObject);
// Where sourceObject is the object whose properties will be copied into another.
1
Ryan Walls

Sie können Objekte zusammenführen, indem Sie meiner Methode folgen

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

var result = mergeObjects([obj1, obj2]);

console.log(result);
document.write("result: <pre>" + JSON.stringify(result, 0, 3) + "</pre>");

function mergeObjects(objectArray) {
    if (objectArray.length) {
        var b = "", i = -1;
        while (objectArray[++i]) {
            var str = JSON.stringify(objectArray[i]);
            b += str.slice(1, str.length - 1);
            if (objectArray[i + 1]) b += ",";
        }
        return JSON.parse("{" + b + "}");
    }
    return {};
}

1

ES5-kompatibler nativer Einliner:

var merged = [obj1, obj2].reduce(function(a, o) { for(k in o) a[k] = o[k]; return a; }, {})
0
toster-cx

Die Zusammenführung von JSON-kompatiblen JavaScript-Objekten

Ich empfehle die Verwendung und Nutzung zerstörungsfreier Methoden, die die ursprüngliche Quelle nicht verändern. 'Object.assign' ist eine destruktive Methode und es ist auch nicht so produktionsfreundlich = weil es in früheren Browsern nicht mehr funktioniert und Sie keine Möglichkeit haben, es mit einer Alternative sauber zu patchen.

Das Zusammenführen von JS-Objekten ist unabhängig von der Lösung immer unerreichbar oder unvollständig. Das Zusammenführen von JSON-kompatiblen Objekten ist jedoch nur einen Schritt entfernt von der Möglichkeit, einen einfachen und portablen Code einer zerstörungsfreien Methode zum Zusammenführen von JS-Objektserien zu einem zurückgegebenen Master zu schreiben, der alle eindeutigen Eigenschaftsnamen und ihre entsprechenden Werte enthält, die in synthetisiert wurden ein einzelnes Master-Objekt für den vorgesehenen Zweck.

Die Tatsache, dass MSIE8 der erste Browser ist, der eine native Unterstützung für das JSON-Objekt hinzugefügt hat, ist eine große Erleichterung, und die Wiederverwendung der bereits vorhandenen Technologie ist immer eine willkommene Gelegenheit.

Das Beschränken Ihres Codes auf JSON-konforme Standardobjekte ist eher ein Vorteil als eine Einschränkung, da diese Objekte auch über das Internet übertragen werden können. Und natürlich gibt es für diejenigen, die eine tiefere Abwärtskompatibilität wünschen, immer einen JSON-Plug, dessen Methoden leicht einer JSON-Variablen im äußeren Code zugewiesen werden können, ohne dass die verwendete Methode geändert oder neu geschrieben werden muss.

function Merge( ){
    var a = [].slice.call( arguments ), i = 0;
        while( a[i] )a[i] = JSON.stringify( a[i++] ).slice( 1,-1 );
        return JSON.parse( "{"+ a.join() +"}" );
    }

(Natürlich kann man ihm immer einen aussagekräftigeren Namen geben, was ich noch nicht entschieden habe; sollte ihn wahrscheinlich JSONmerge nennen)

Der Anwendungsfall:

var master = Merge( obj1, obj2, obj3, ...objn );

Nun, im Gegensatz zum Object.assign Dadurch bleiben alle Objekte unberührt und in ihrem ursprünglichen Zustand (falls Sie etwas falsch gemacht haben und die Zusammenführungsobjekte neu anordnen müssen oder sie separat für einen anderen Vorgang verwenden können, bevor Sie sie erneut zusammenführen).

Die Anzahl der Merge-Argumente ist ebenfalls begrenzt nur durch die Längenbeschränkung der Argumente [die sehr groß ist]. Das von Haus aus unterstützte JSON-Parsing/Stringify ist bereits maschinenoptimiert. Dies bedeutet, dass es schneller sein sollte als jede skriptgesteuerte Form einer JS-Schleife. Die Iteration über gegebene Argumente erfolgt mit der while - erwiesenermaßen die schnellste Schleife in JS.

Es schadet nicht, kurz zu erwähnen, dass wir bereits wissen, dass doppelte Eigenschaften der eindeutigen Objektbezeichnungen (Schlüssel) von dem späteren Objekt überschrieben werden, das dieselbe Schlüsselbezeichnung enthält, was bedeutet, dass Sie die Kontrolle darüber haben, welche Eigenschaft die übernimmt vorher, indem Sie einfach die Argumentliste bestellen oder neu anordnen. Und der Vorteil, ein sauberes und aktualisiertes Master-Objekt ohne Dupes als endgültige Ausgabe zu erhalten.

;
var obj1 = {a:1}, obj2 = {b:2}, obj3 = {c:3}
;
function Merge( ){
    var a = [].slice.call( arguments ), i = 0;
        while( a[i] )a[i] = JSON.stringify( a[i++] ).slice( 1,-1 );
        return JSON.parse( "{"+ a.join() +"}" );
    }
;
var master = Merge( obj1, obj2, obj3 )
;
console.log( JSON.stringify( master ) )
;
0
Bekim Bacaj

Diese Lösung erstellt ein neues Objekt und kann mehrere Objekte verarbeiten.

Außerdem ist es rekursiv und Sie können das Wetter auswählen wollen bis Werte überschreiben und Objekte.

    function extendObjects() {

        var newObject        = {};
        var overwriteValues  = false;
        var overwriteObjects = false;

        for ( var indexArgument = 0; indexArgument < arguments.length; indexArgument++ ) {

            if ( typeof arguments[indexArgument] !== 'object' ) {

                if ( arguments[indexArgument] == 'overwriteValues_True' ) {

                    overwriteValues = true;            
                } else if ( arguments[indexArgument] == 'overwriteValues_False' ) {

                    overwriteValues = false;                             
                } else if ( arguments[indexArgument] == 'overwriteObjects_True' ) {

                    overwriteObjects = true;     
                } else if ( arguments[indexArgument] == 'overwriteObjects_False' ) {

                    overwriteObjects = false; 
                }

            } else {

                extendObject( arguments[indexArgument], newObject, overwriteValues, overwriteObjects );
            }

        }

        function extendObject( object, extendedObject, overwriteValues, overwriteObjects ) {

            for ( var indexObject in object ) {

                if ( typeof object[indexObject] === 'object' ) {

                    if ( typeof extendedObject[indexObject] === "undefined" || overwriteObjects ) {
                        extendedObject[indexObject] = object[indexObject];
                    }

                    extendObject( object[indexObject], extendedObject[indexObject], overwriteValues, overwriteObjects );

                } else {

                    if ( typeof extendedObject[indexObject] === "undefined" || overwriteValues ) {
                        extendedObject[indexObject] = object[indexObject];
                    }

                }

            }     

            return extendedObject;

        }

        return newObject;
    }

    var object1           = { a : 1, b : 2, testArr : [888, { innArr : 1 }, 777 ], data : { e : 12, c : { lol : 1 }, rofl : { O : 3 } } };
    var object2           = { a : 6, b : 9, data : { a : 17, b : 18, e : 13, rofl : { O : 99, copter : { mao : 1 } } }, hexa : { tetra : 66 } };
    var object3           = { f : 13, g : 666, a : 333, data : { c : { xD : 45 } }, testArr : [888, { innArr : 3 }, 555 ]  };

    var newExtendedObject = extendObjects( 'overwriteValues_False', 'overwriteObjects_False', object1, object2, object3 );

Inhalt von newExtendedObject:

{"a":1,"b":2,"testArr":[888,{"innArr":1},777],"data":{"e":12,"c":{"lol":1,"xD":45},"rofl":{"O":3,"copter":{"mao":1}},"a":17,"b":18},"hexa":{"tetra":66},"f":13,"g":666}

Geige: http://jsfiddle.net/o0gb2umb/

0
Scdev

Ich habe Object.create () verwendet, um die Standardeinstellungen beizubehalten (mithilfe von __proto__ oder Object.getPrototypeOf ()). 

function myPlugin( settings ){
    var defaults = {
        "keyName": [ "string 1", "string 2" ]
    }
    var options = Object.create( defaults );
    for (var key in settings) { options[key] = settings[key]; }
}
myPlugin( { "keyName": ["string 3", "string 4" ] } );

Auf diese Weise kann ich später immer 'concat ()' oder 'Push ()'.

var newArray = options['keyName'].concat( options.__proto__['keyName'] );

Hinweis : Sie müssen vor der Verkettung eine hasOwnProperty-Prüfung durchführen, um Doppelarbeit zu vermeiden.

0
Egor Kloos

Ein möglicher Weg, dies zu erreichen, ist folgender.

if (!Object.prototype.merge){
    Object.prototype.merge = function(obj){
        var self = this;
        Object.keys(obj).forEach(function(key){
            self[key] = obj[key]
        });
    }
};

Ich weiß nicht, ob es besser ist als die anderen Antworten. In dieser Methode fügen Sie den Prototyp merge function zu Objects hinzu. Auf diese Weise können Sie obj1.merge(obj2); aufrufen.

Hinweis: Sie sollten Ihr Argument überprüfen, um zu sehen, ob es ein Objekt ist, und eine richtige Error 'werfen'. Wenn nicht, wirft Object.keys einen 'Fehler'

0
Yaki Klein

Mit dem folgenden Helfer können Sie zwei Objekte zu einem neuen Objekt zusammenführen:

function extend(obj, src) {
    for (var key in src) {
        if (src.hasOwnProperty(key)) obj[key] = src[key];
    }
    return obj;
}

// example
var a = { foo: true }, b = { bar: false };
var c = extend(a, b);

console.log(c);
// { foo: true, bar: false }

Dies ist normalerweise hilfreich, wenn Sie ein Optionsdict mit den Standardeinstellungen in einer Funktion oder einem Plugin zusammenführen.

Wenn für IE 8 keine Unterstützung erforderlich ist, können Sie stattdessen Object.keys für dieselbe Funktionalität verwenden:

function extend(obj, src) {
    Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
    return obj;
}

Dies beinhaltet etwas weniger Code und ist etwas schneller.

0
gildniy

let obj1 = {a:1, b:2};
let obj2 = {c:3, d:4};
let merged = {...obj1, ...obj2};
console.log(merged);

0
Tejas Savaliya
A={a:1,b:function(){alert(9)}}
B={a:2,c:3}
A.merge = function(){for(var i in B){A[i]=B[i]}}
A.merge()

Das Ergebnis ist: {a: 2, c: 3, b: function ()}

0
jleviaguirre

Dies führt obj zu einem "Standard" def zusammen. obj hat Vorrang für alles, was in beiden existiert, da obj in def kopiert wird. Beachten Sie auch, dass dies rekursiv ist.

function mergeObjs(def, obj) {
    if (typeof obj == 'undefined') {
        return def;
    } else if (typeof def == 'undefined') {
        return obj;
    }
    for (var i in obj) {
        if (obj[i] != null && obj[i].constructor == Object) {
            def[i] = mergeObjs(def[i], obj[i]);
        } else {
            def[i] = obj[i];
        }
    }
    return def;
}

a = {x : {y : [123]}}
b = {x : {z : 123}}
console.log(mergeObjs(a, b));
// {x: {y : [123], z : 123}}
0
Aram Kocharyan

Wir können ein leeres Objekt erstellen und mit for-loop kombinieren:

var obj1 = {
  id: '1',
  name: 'name'
}

var obj2 = {
  c: 'c',
  d: 'd'
}

var obj3 = {}

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


console.log( obj1, obj2, obj3)

0
aircraft

Wenn Sie Dojo Toolkit verwenden, können Sie zwei Objekte am besten mit einem Mixin zusammenführen. 

Hier ist das Beispiel für Dojo Toolkit Mixin:

// Dojo 1.7+ (AMD)
require(["dojo/_base/lang"], function(lang){
  var a = { b:"c", d:"e" };
  lang.mixin(a, { d:"f", g:"h" });
  console.log(a); // b:c, d:f, g:h
});

// Dojo < 1.7
var a = { b:"c", d:"e" };
dojo.mixin(a, { d:"f", g:"h" });
console.log(a); // b:c, d:f, g:h

Für weitere Details bitte mixin.

0
Vikash Pandey

Sie können jedem Objekt eine Standardmethode für das Zusammenführen (vielleicht einen besseren Namen "erben") zuweisen:

Es sollte entweder mit Objekten oder instanziierten Funktionen funktionieren.

Der folgende Code behandelt, wenn gewünscht, die zusammengeführten Werte überschrieben:

Object.prototype.merge = function(obj, override) {
// Don't override by default

    for (var key in obj) {
        var n = obj[key];
        var t = this[key];
        this[key] = (override && t) ? n : t;
    };

};

Testdaten sind unten:

var Mammal = function () {
    this.eyes = 2;
    this.thinking_brain = false;
    this.say = function () {
    console.log('screaming like a mammal')};
}

var Human = function () {
    this.thinking_brain = true;
    this.say = function() {console.log('shouting like a human')};
}

john = new Human();

// Extend mammal, but do not override from mammal
john.merge(new Mammal());
john.say();

// Extend mammal and override from mammal
john.merge(new Mammal(), true);
john.say();
0
Paul

Eine andere Methode:

function concat_collection(obj1, obj2) {
    var i;
    var arr = new Array();

    var len1 = obj1.length;
    for (i=0; i<len1; i++) {
        arr.Push(obj1[i]);
    }

    var len2 = obj2.length;
    for (i=0; i<len2; i++) {
        arr.Push(obj2[i]);
    }

    return arr;
}

var ELEMENTS = concat_collection(A,B);
for(var i = 0; i < ELEMENTS.length; i++) {
    alert(ELEMENTS[i].value);
}
0
T.Todua