Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten.Erfahre mehr über dieses Experiment.
Tiefkopie
EineTiefkopie eines Objekts ist eine Kopie, deren Eigenschaften nicht dieselben Referenzen teilen (auf dieselben zugrunde liegenden Werte verweisen) wie die des Ausgangsobjekts, aus dem die Kopie erstellt wurde. Dadurch können Sie sicher sein, dass weder eine Änderung der Quelle noch der Kopie dazu führt, dass sich das andere Objekt ebenfalls ändert. Dieses Verhalten steht im Gegensatz zum Verhalten einerFlachkopie, bei der Änderungen an verschachtelten Eigenschaften in der Quelle oder der Kopie dazu führen können, dass sich das andere Objekt ebenfalls ändert.
Zwei Objekteo1 undo2 sindstrukturell äquivalent, wenn ihr beobachtbares Verhalten dasselbe ist. Dieses Verhalten umfasst:
- Die Eigenschaften von
o1undo2haben dieselben Namen in derselben Reihenfolge. - Die Werte ihrer Eigenschaften sind strukturell äquivalent.
- Ihre Prototypenketten sind strukturell äquivalent (obwohl es sich bei der Betrachtung der strukturellen Äquivalenz normalerweise um einfache Objekte handelt, die beide von
Object.prototypeerben).
Strukturell äquivalente Objekte können entweder dasselbe Objekt sein (o1 === o2) oderKopien (o1 !== o2). Da äquivalente primitive Werte immer als gleich verglichen werden, können Sie keine Kopien davon erstellen.
Wir können Tiefkopien nun formeller definieren als:
- Sie sind nicht dasselbe Objekt (
o1 !== o2). - Die Eigenschaften von
o1undo2haben dieselben Namen in derselben Reihenfolge. - Die Werte ihrer Eigenschaften sind Tiefkopien voneinander.
- Ihre Prototypenketten sind strukturell äquivalent.
Tiefkopien können entweder ihre Prototypenketten kopiert haben oder nicht (häufig sind sie es nicht). Aber zwei Objekte mit strukturell nicht äquivalenten Prototypenketten (zum Beispiel eines ist ein Array und das andere ein einfaches Objekt) sind niemals Kopien voneinander.
Die Kopie eines Objekts, dessen Eigenschaften alle primitive Werte haben, entspricht sowohl der Definition einer Tiefkopie als auch einerFlachkopie. Es ist jedoch wenig sinnvoll, in einem solchen Fall von der Tiefe einer Kopie zu sprechen, da das Objekt keine verschachtelten Eigenschaften hat und wir in der Regel über Tiefkopieren im Kontext der Veränderung verschachtelter Eigenschaften sprechen.
In JavaScript erzeugen Standardmethoden zum Kopieren von Objekten (Spread-Syntax,Array.prototype.concat(),Array.prototype.slice(),Array.from() undObject.assign()) keine Tiefkopien (stattdessen erstellen sie Flachkopien).
Eine Möglichkeit, eine Tiefkopie eines JavaScript-Objekts zu erstellen, wenn esserialisiert werden kann, ist die Verwendung vonJSON.stringify(), um das Objekt in einen JSON-String zu konvertieren, und dannJSON.parse(), um den String zurück in ein (vollständig neues) JavaScript-Objekt zu konvertieren:
const ingredientsList = ["noodles", { list: ["eggs", "flour", "water"] }];const ingredientsListDeepCopy = JSON.parse(JSON.stringify(ingredientsList));Da eine Tiefkopie keine Referenzen zu ihrem Quellobjekt teilt, wirken sich Änderungen an der Tiefkopie nicht auf das Quellobjekt aus.
// Change the value of the 'list' property in ingredientsListDeepCopy.ingredientsListDeepCopy[1].list = ["rice flour", "water"];// The 'list' property does not change in ingredients_list.console.log(ingredientsList[1].list);// Array(3) [ "eggs", "flour", "water" ]Das im obigen Code gezeigte Objekt ist jedoch einfach genug, umserialisierbar zu sein. Viele JavaScript-Objekte sind jedoch nicht serialisierbar — zum BeispielFunktionen (mit Closures),Symbole, Objekte, die HTML-Elemente in derHTML DOM API darstellen, rekursive Daten und viele andere Fälle. Der Aufruf vonJSON.stringify(), um die Objekte in diesen Fällen zu serialisieren, wird fehlschlagen. Es gibt daher keine Möglichkeit, Tiefkopien solcher Objekte zu erstellen.
Die Web-APIstructuredClone() erstellt ebenfalls Tiefkopien und bietet den Vorteil, dassübertragbare Objekte in der Quelle an die neue Kopieübertragen werden können, anstatt nur kopiert zu werden. Sie unterstützt auch mehr Datentypen, wie z.B.Error. Beachten Sie jedoch, dassstructuredClone() keine Funktion der JavaScript-Sprache selbst ist — es ist eine Funktion von Browsern und anderen JavaScript-Hosts, die Web-APIs implementieren. Und der Aufruf vonstructuredClone(), um ein nicht serialisierbares Objekt zu klonen, wird auf die gleiche Weise fehlschlagen wie der Aufruf vonJSON.stringify() zur Serialisierung.
In diesem Artikel
Siehe auch
- Verwandte Glossarbegriffe:
Window.structuredClone()WorkerGlobalScope.structuredClone()