In der Lodash-Bibliothek kann jemand eine bessere Erklärung für merge und extend / assign bereitstellen.
Es ist eine einfache Frage, aber die Antwort entzieht sich mir dennoch.
In der Lodash-Bibliothek kann jemand eine bessere Erklärung für merge und extend / assign bereitstellen.
Es ist eine einfache Frage, aber die Antwort entzieht sich mir dennoch.
So funktioniert erweitern
/zuweisen
: Für jedes Attribut in der Quelle wird dessen Wert unverändert in das Ziel kopiert. Wenn die Attributwerte selbst Objekte sind, findet keine rekursive Traversierung ihrer Attribute statt. Das gesamte Objekt wird aus der Quelle genommen und im Ziel gesetzt.
So funktioniert verschmelzen
: Für jedes Attribut in der Quelle wird überprüft, ob das Attribut selbst ein Objekt ist. Falls ja, wird rekursiv nach unten gegangen und versucht, die Eigenschaften des untergeordneten Objekts von der Quelle auf das Ziel abzubilden. Im Wesentlichen verschmelzen wir also die Objekthierarchie von der Quelle zum Ziel. Während es bei erweitern
/zuweisen
einfach eine Kopie der Eigenschaften von der Quelle zum Ziel auf einer Ebene ist.
Hier ist ein einfaches JSBin-Beispiel, das dies kristallklar macht: http://jsbin.com/uXaqIMa/2/edit?js,console
Hier ist eine ausführlichere Version, die auch ein Array im Beispiel enthält: http://jsbin.com/uXaqIMa/1/edit?js,console
_.merge(object, [Quellen], [Anpasser], [thisArg])
_.assign(object, [Quellen], [Anpasser], [thisArg])
_.extend(object, [Quellen], [Anpasser], [thisArg])
_.defaults(object, [Quellen])
_.defaultsDeep(object, [Quellen])
_.extend
ist ein Alias für _.assign
, also sind sie identischnull
auf die gleiche Weise_.defaults
und _.defaultsDeep
verarbeiten die Argumente in umgekehrter Reihenfolge im Vergleich zu den anderen (obwohl das erste Argument immer noch das Zielobjekt ist)_.merge
und _.defaultsDeep
werden Unterobjekte zusammenführen und die anderen werden auf der Basisebene überschreiben_.assign
und _.extend
werden einen Wert mit undefined
überschreiben_.assign ({}, { a: 'a' }, { a: 'bb' }) // => { a: "bb" }
_.merge ({}, { a: 'a' }, { a: 'bb' }) // => { a: "bb" }
_.defaults ({}, { a: 'a' }, { a: 'bb' }) // => { a: "a" }
_.defaultsDeep({}, { a: 'a' }, { a: 'bb' }) // => { a: "a" }
_.assign
behandelt undefined
, aber die anderen werden es überspringen_.assign ({}, { a: 'a' }, { a: undefined }) // => { a: undefined }
_.merge ({}, { a: 'a' }, { a: undefined }) // => { a: "a" }
_.defaults ({}, { a: undefined }, { a: 'bb' }) // => { a: "bb" }
_.defaultsDeep({}, { a: undefined }, { a: 'bb' }) // => { a: "bb" }
null
auf die gleiche Weise_.assign ({}, { a: 'a' }, { a: null }) // => { a: null }
_.merge ({}, { a: 'a' }, { a: null }) // => { a: null }
_.defaults ({}, { a: null }, { a: 'bb' }) // => { a: null }
_.defaultsDeep({}, { a: null }, { a: 'bb' }) // => { a: null }
_.merge
und _.defaultsDeep
werden Unterobjekte zusammenführen_.assign ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "b": "bb" }}
_.merge ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a", "b": "bb" }}
_.defaults ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a" }}
_.defaultsDeep({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a", "b": "bb" }}
_.assign ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "bb" ] }
_.merge ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "bb" ] }
_.defaults ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "a" ] }
_.defaultsDeep({}, {a:['a']}, {a:['bb']}) // => { "a": [ "a" ] }
a={a:'a'}; _.assign (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.merge (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.defaults (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.defaultsDeep(a, {b:'bb'}); // a => { a: "a", b: "bb" }
Hinweis: Wie @Mistic herausgestellt hat, behandelt Lodash Arrays als Objekte, bei denen die Schlüssel den Index im Array darstellen.
_.assign ([], ['a'], ['bb']) // => [ "bb" ]
_.merge ([], ['a'], ['bb']) // => [ "bb" ]
_.defaults ([], ['a'], ['bb']) // => [ "a" ]
_.defaultsDeep([], ['a'], ['bb']) // => [ "a" ]
_.assign ([], ['a','b'], ['bb']) // => [ "bb", "b" ]
_.merge ([], ['a','b'], ['bb']) // => [ "bb", "b" ]
_.defaults ([], ['a','b'], ['bb']) // => [ "a", "b" ]
_.defaultsDeep([], ['a','b'], ['bb']) // => [ "a", "b" ]
Ein weiterer Unterschied, auf den geachtet werden muss, ist der Umgang mit undefined
Werten:
mergeInto = { a: 1}
toMerge = {a : undefined, b:undefined}
lodash.extend({}, mergeInto, toMerge) // => {a: undefined, b:undefined}
lodash.merge({}, mergeInto, toMerge) // => {a: 1, b:undefined}
Also wird merge
keine undefined
Werte in definierte Werte zusammenführen.
Es könnte auch hilfreich sein, zu berücksichtigen, was sie aus semantischer Sicht tun:
weist die Werte der Eigenschaften seines zweiten Parameters und so weiter zu,
als Eigenschaften mit demselben Namen des ersten Parameters. (flache Kopie & Überschreibung)
merge ist wie assign, weist jedoch keine Objekte zu, sondern repliziert sie stattdessen.
(Tiefe Kopie)
stellt Standardwerte für fehlende Werte bereit.
wird also nur Werte für Schlüssel zuweisen, die im Quellobjekt noch nicht existieren.
funktioniert wie _defaults, aber wie merge wird es Objekte nicht einfach kopieren
und stattdessen Rekursion verwenden.
Ich glaube, dass es hilfreich ist, diese Methoden aus semantischer Sicht zu betrachten, um besser "erraten" zu können, wie sich die verschiedenen Szenarien von existierenden und nicht existierenden Werten verhalten würden.
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.