3287 Stimmen

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

Ich muss in der Lage sein, zwei (sehr einfache) JavaScript-Objekte zur Laufzeit zu verschmelzen. Zum Beispiel würde ich gerne:

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

obj1.merge(obj2);

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

Gibt es eine eingebaute Möglichkeit, dies zu tun? Ich brauche keine Rekursion, und ich muss nicht Funktionen zusammenführen, nur Methoden auf flache Objekte.

0 Stimmen

Es ist erwähnenswert diese Antwort auf eine ähnliche Frage , die zeigt, wie man "eine Ebene tiefer" zusammenführt. Das heißt, es werden Werte mit doppelten Schlüsseln zusammengeführt (anstatt den ersten Wert mit dem zweiten zu überschreiben), aber es wird nicht weiter rekursiert als das. IMHO ist es ein guter, sauberer Code für diese Aufgabe.

0 Stimmen

Übrigens führen die ersten paar Antworten eine "oberflächliche" Zusammenführung durch: Wenn derselbe Schlüssel sowohl in obj1 als auch in obj2 vorhanden ist, wird der Wert in obj2 beibehalten, der Wert in obj1 wird gelöscht. Wenn z.B. das Beispiel der Frage var obj2 = { animal: 'dog', food: 'bone' }; wäre die Verschmelzung { food: 'bone', car: 'ford', animal: 'dog' } . Wenn Sie mit "verschachtelten Daten" arbeiten und eine "tiefe Zusammenführung" wünschen, suchen Sie nach Antworten, die "tiefe Zusammenführung" oder "Rekursion" erwähnen. Wenn Sie Werte haben, die arrays verwenden Sie dann die Option "arrayMerge" von github "TehShrike/deepmerge", wie erwähnt aquí .

17voto

antitoxic Punkte 3666

Es gibt eine Bibliothek namens deepmerge auf GitHub : Das scheint sich zu etablieren. Es ist ein eigenständiges Programm, das sowohl über die npm und bower-Paketmanager.

Ich wäre geneigt, dies zu verwenden oder zu verbessern, anstatt den Code aus den Antworten zu kopieren und einzufügen.

16voto

David Coallier Punkte 106

Am besten fügen Sie dazu mit Object.defineProperty eine eigene Eigenschaft hinzu, die nicht aufzählbar ist.

Auf diese Weise können Sie immer noch über die Eigenschaften Ihrer Objekte iterieren, ohne das neu erstellte "extend" zu haben, 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(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});

Wenn Sie das geschafft haben, können Sie es tun:

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

obj.extend(replacement);

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

15voto

Dinusha Punkte 692

Sie können einfach jQuery verwenden 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 y obj2

15voto

ephemient Punkte 189038

Prototyp hat dies:

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

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

14voto

Logan Punkte 547

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

ES5 und frühere Versionen

Diese Methode ist für ES5 und frühere Versionen - es gibt viele andere Antworten, die sich mit ES6 befassen.

Ich habe nichts gesehen "tief" Objektzusammenführung unter Verwendung der arguments Eigentum. Hier ist meine Antwort - kompakt & rekursiv , so dass eine unbegrenzte Anzahl von Objektargumenten übergeben werden kann:

function extend() {
    for (var o = {}, i = 0; i < arguments.length; i++) {
        // Uncomment to skip arguments that are not objects (to prevent errors)
        // 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;
}

Ejemplo

/**
 * Extend objects
 */
function extend() {
    for (var o = {}, i = 0; i < arguments.length; i++) {
        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;
}

/**
 * Example
 */
document.write(JSON.stringify(extend({
    api: 1,
    params: {
        query: 'hello'
    }
}, {
    params: {
        query: 'there'
    }
})));
// outputs {"api": 1, "params": {"query": "there"}}

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X