Angenommen, ich habe eine options
Variable und möchte einen Standardwert festlegen.
Was ist der Vor- / Nachteil dieser beiden Alternativen?
Verwenden der Objektverteilung
options = {...optionsDefault, ...options};
Oder mit Object.assign
options = Object.assign({}, optionsDefault, options);
Dies ist das Commit , das mich wundern ließ.
javascript
ecmascript-6
Olivier Tassinari
quelle
quelle
Antworten:
Dies ist nicht unbedingt erschöpfend.
Syntax verbreiten
Vorteile:
Wenn Sie Code für die Ausführung in Umgebungen ohne native Unterstützung erstellen, können Sie diese Syntax möglicherweise nur kompilieren (im Gegensatz zur Verwendung einer Polyfüllung). (Zum Beispiel mit Babel.)
Weniger ausführlich.
Nachteile:
Als diese Antwort ursprünglich geschrieben wurde, war dies ein Vorschlag , der nicht standardisiert war. Überlegen Sie bei der Verwendung von Vorschlägen, was Sie tun würden, wenn Sie jetzt Code damit schreiben und dieser auf dem Weg zur Standardisierung nicht standardisiert oder geändert wird. Dies wurde inzwischen in ES2018 standardisiert.
Wörtlich, nicht dynamisch.
Object.assign()
Vorteile:
Standardisiert.
Dynamisch. Beispiel:
Nachteile:
Das hängt nicht direkt mit dem zusammen, was Sie fragen. Dieser Code wurde nicht verwendet
Object.assign()
, sondern Benutzercode (object-assign
), der dasselbe tut. Sie scheinen diesen Code mit Babel zu kompilieren (und ihn mit Webpack zu bündeln), worüber ich gesprochen habe: die Syntax, die Sie einfach kompilieren können. Sie zogen es anscheinend vor, diesobject-assign
als Abhängigkeit einbeziehen zu müssen, die in ihren Build einfließen würde.quelle
Object.assign()
. Oder Sie können manuell über ein Array von Objekten und ihre eigenen Requisiten iterieren und sie manuell einem Ziel zuweisen und es noch ausführlicher machen: PAls Referenzobjekt wird Rest / Spread in ECMAScript 2018 als Stufe 4 finalisiert. Den Vorschlag finden Sie hier .
Das Zurücksetzen und Verteilen von Objekten funktioniert größtenteils auf die gleiche Weise. Der Hauptunterschied besteht darin, dass Spread Eigenschaften definiert, während Object.assign () sie festlegt . Dies bedeutet, dass Object.assign () Setter auslöst.
Es ist zu beachten, dass Objektrest / Spread 1: 1 anders als Object.assign () zugeordnet ist und sich anders verhält als Array (iterable) Spread. Wenn Sie beispielsweise ein Array verteilen, werden Nullwerte verteilt. Bei Verwendung von Objektstreuung werden Nullwerte jedoch stillschweigend auf nichts verteilt.
Array (Iterable) Spread-Beispiel
Beispiel für die Objektverteilung
Dies steht im Einklang mit der Funktionsweise von Object.assign (). Beide schließen den Nullwert ohne Fehler aus.
quelle
Object.assign
, Setter zu verwenden.Object.assign({set a(v){this.b=v}, b:2}, {a:4}); // {b: 4}
vs.{...{set a(v){this.b=v}, b:2}, ...{a:4}}; // {a: 4, b: 2}
const x = {c: null};
. In diesem Fall, AFAIK, würden wir ein Verhalten wie das Array sehen ://{a: 1, b: 2, c: null}
.Ich denke, ein großer Unterschied zwischen dem Spread-Operator und dem
Object.assign
, der in den aktuellen Antworten nicht erwähnt zu werden scheint, besteht darin, dass der Spread-Operator den Prototyp des Quellobjekts nicht auf das Zielobjekt kopiert. Wenn Sie einem Objekt Eigenschaften hinzufügen möchten und nicht ändern möchten, um welche Instanz es sich handelt, müssen Sie diese verwendenObject.assign
. Das folgende Beispiel sollte dies demonstrieren:quelle
errorExtendedUsingAssign === error
sich jedocherrorExtendedUsingSpread
um ein neues Objekt (und der Prototyp wurde nicht kopiert).let target = Object.create(source); Object.assign(target, source);
Wie andere bereits erwähnt haben,
Object.assign()
erfordert in diesem Moment des Schreibens eine Polyfüllung, und die Objektverbreitung...
erfordert ein gewisses Transpiling (und möglicherweise auch eine Polyfüllung), um zu arbeiten.Betrachten Sie diesen Code:
Diese beiden erzeugen die gleiche Ausgabe.
Hier ist die Ausgabe von Babel an ES5:
Das ist mein bisheriges Verständnis.
Object.assign()
ist eigentlich standardisiert, da als objektverbreitung...
noch nicht erfolgt. Das einzige Problem ist die Browserunterstützung für die ersteren und in Zukunft auch für die letzteren.Spielen Sie hier mit dem Code
Hoffe das hilft.
quelle
{}
sollte die Inkonsistenz beheben.Der Objektverbreitungsoperator (...) funktioniert in Browsern nicht, da er noch nicht Teil einer ES-Spezifikation ist, sondern nur ein Vorschlag. Die einzige Möglichkeit besteht darin, es mit Babel (oder ähnlichem) zu kompilieren.
Wie Sie sehen können, handelt es sich nur um syntaktischen Zucker über Object.assign ({}).
Soweit ich sehen kann, sind dies die wichtigen Unterschiede.
...
für Objekte ist nicht standardisiert...
schützt Sie vor versehentlichem Mutieren des Objekts...
wird Object.assign in Browsern ohne es polyfill...
benötigt weniger Code, um dieselbe Idee auszudrückenquelle
Object.assign
, da der Spread-Operator Ihnen immer ein neues Objekt gibt.Ich möchte den Status der ES-Funktion "Spread Object Merge" in Browsern und im Ökosystem über Tools zusammenfassen.
Spec
Browser: bald in Chrome, in SF, Firefox (Version 60, IIUC)
Werkzeuge: Knoten 8.7, TS 2.1
Links
Codebeispiel (dient gleichzeitig als Kompatibilitätstest)
Nochmals: Zum Zeitpunkt des Schreibens funktioniert dieses Beispiel ohne Transpilation in Chrome (60+), Firefox Developer Edition (Vorschau von Firefox 60) und Node (8.7+).
Warum antworten?
Ich schreibe dies 2,5 Jahre nach der ursprünglichen Frage. Aber ich hatte genau die gleiche Frage, und hier hat Google mich hingeschickt. Ich bin ein Sklave von SOs Mission, den langen Schwanz zu verbessern.
Da dies eine Erweiterung der "Array Spread" -Syntax ist, war es für mich sehr schwierig zu googeln und in Kompatibilitätstabellen schwer zu finden. Das nächste, das ich finden konnte, ist Kangax "Property Spread" , aber dieser Test enthält nicht zwei Spreads im selben Ausdruck (keine Zusammenführung). Auch der Name auf den Statusseiten für Vorschläge / Entwürfe / Browser verwendet alle "Eigenschaftsverteilung", aber es scheint mir, dass dies ein "erster Grundsatz" war, zu dem die Community nach den Vorschlägen zur Verwendung der Verbreitungssyntax für "Objektzusammenführung" gelangt ist. (Dies könnte erklären, warum es so schwierig ist, zu googeln.) Daher dokumentiere ich meine Ergebnisse hier, damit andere Links zu dieser bestimmten Funktion anzeigen, aktualisieren und kompilieren können. Ich hoffe es fängt an. Bitte helfen Sie dabei, die Nachricht von der Landung in der Spezifikation und in den Browsern zu verbreiten.
Zuletzt hätte ich diese Informationen als Kommentar hinzugefügt, aber ich konnte sie nicht bearbeiten, ohne die ursprüngliche Absicht der Autoren zu brechen. Insbesondere kann ich den Kommentar von @ ChillyPenguin nicht bearbeiten, ohne dass er seine Absicht verliert, @RichardSchulte zu korrigieren. Aber Jahre später stellte sich Richard als richtig heraus (meiner Meinung nach). Also schreibe ich stattdessen diese Antwort in der Hoffnung, dass sie irgendwann bei den alten Antworten an Bedeutung gewinnt (könnte Jahre dauern, aber genau darum geht es schließlich beim Long-Tail- Effekt).
quelle
HINWEIS: Spread ist NICHT nur syntaktischer Zucker um Object.assign. Sie arbeiten hinter den Kulissen sehr unterschiedlich.
Object.assign wendet Setter auf ein neues Objekt an, Spread nicht. Außerdem muss das Objekt iterierbar sein.
Kopieren Verwenden Sie diese Option, wenn Sie den Wert des Objekts in diesem Moment benötigen und nicht möchten, dass dieser Wert Änderungen widerspiegelt, die von anderen Eigentümern des Objekts vorgenommen wurden.
Verwenden Sie diese Option, um eine flache Kopie des Objekts zu erstellen. Es wird empfohlen, unveränderliche Eigenschaften immer zu kopieren. Da veränderbare Versionen an unveränderliche Eigenschaften übergeben werden können, stellt copy sicher, dass Sie immer mit einem unveränderlichen Objekt arbeiten
Assign Assign ist etwas anderes als das Kopieren. Assign generiert einen Setter, der den Wert direkt der Instanzvariablen zuweist, anstatt ihn zu kopieren oder beizubehalten. Wenn der Getter einer Zuweisungseigenschaft aufgerufen wird, wird ein Verweis auf die tatsächlichen Daten zurückgegeben.
quelle
Andere Antworten sind alt, konnten keine gute Antwort bekommen.
Das folgende Beispiel bezieht sich auf Objektliterale und hilft, wie sich beide ergänzen können und wie sie sich nicht ergänzen können (daher Unterschied):
Einige weitere kleine Beispiele hier, auch für Array & Objekt:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
quelle
Dies ist jetzt Teil von ES6, daher standardisiert und auch auf MDN dokumentiert: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Es ist sehr bequem zu bedienen und macht neben der Objektzerstörung viel Sinn.
Der einzige verbleibende Vorteil, der oben aufgeführt ist, sind die dynamischen Funktionen von Object.assign (). Dies ist jedoch so einfach wie das Verteilen des Arrays innerhalb eines Literalobjekts. In der kompilierten Babel-Ausgabe wird genau das verwendet, was mit Object.assign () demonstriert wird.
Die richtige Antwort wäre also, die Objektverteilung zu verwenden, da sie jetzt standardisiert und weit verbreitet ist (siehe Reagieren, Reduzieren usw.), einfach zu verwenden ist und alle Funktionen von Object.assign () bietet.
quelle
Ich möchte dieses einfache Beispiel hinzufügen, wenn Sie Object.assign verwenden müssen.
Es kann nicht klar sein, wenn Sie JavaScript verwenden. Mit TypeScript ist es jedoch einfacher, eine Instanz einer Klasse zu erstellen
quelle