# 3 Möglichkeiten zum Klonen von Objekten in JavaScript

Veröffentlicht in: Articles | 0

Da Objekte in JavaScript Referenzwerte sind, können Sie nicht einfach mit der =kopieren. Aber keine Sorge, hier sind 3 Möglichkeiten für Sie, ein Objekt zu klonen 👍

# Objekte sind Referenztypen

Ihre erste Frage könnte sein, warum kann ich nicht =. Mal sehen, was passiert,wenn wir das tun:

const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);

Bisher scheinen beide Objekte dasselbe auszugeben. Also kein problem, richtig., Aber mal sehen, was passiert, wenn wir unser zweites Objekt bearbeiten:

const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱

WTH?! Ich habe obj2 aber warum war obj ebenfalls betroffen? Das liegt daran, dass Objekte Referenztypen sind. Wenn Sie also =, wird der Zeiger auf den belegten Speicherplatz kopiert. Referenztypen enthalten keine Werte, sie sind ein Zeiger auf den Wert im Speicher.

Wenn Sie mehr darüber erfahren möchten, schauen Sie sich Gordons Zhu Watch and Code Course an. Es ist kostenlos, sich anzumelden und das Video „Vergleich mit Objekten“anzusehen., Er gibt eine super tolle Erklärung dazu.

# 1. Mit Spread

Mit spread wird Ihr Objekt geklont. Beachten Sie, dass dies eine flache Kopie sein wird. Ab diesem Beitrag befindet sich der Spread-Operator zum Klonen von Objekten in Stufe 4. Es ist also noch nicht offiziell in den Spezifikationen. Wenn Sie dies verwenden würden, müssten Sie es mit Babel (oder ähnlichem) kompilieren.

const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }

# 2. Objekt verwenden.assign

Alternativ Object.assign ist in der offiziellen Version und wird auch eine flache Kopie des Objekts erstellen.,

const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }

Beachten Sie als erstes Argument die leere {} Dadurch wird sichergestellt, dass Sie das ursprüngliche Objekt nicht mutieren 👍

# 3. Wenn Sie JSON

Auf diese Weise verwenden, erhalten Sie eine tiefe Kopie. Jetzt werde ich erwähnen, dies ist eine schnelle und schmutzige Art, ein Objekt tief zu klonen. Für eine robustere Lösung, die ich empfehlen würde, mit so etwas wie lodash

const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }

# Lodash DeepClone vs JSON

Hier ist ein Kommentar aus der community. Ja, es war für meinen vorherigen Beitrag, Wie man ein Array tief klont ., Aber die Idee gilt immer noch für Objekte.

Alfredo Salzillo: Ich möchte Sie darauf hinweisen, dass es einige Unterschiede zwischen deepClone und JSON gibt.stringify/analysieren.

  • JSON.stringify / parse funktioniert nur mit Number und String und Object Literal ohne Funktions – oder Symboleigenschaften.
  • deepClone arbeiten mit allen Typen, Funktion und Symbol werden als Referenz kopiert.

Hier ist ein Beispiel:

@OlegVaraksin : Die JSON-Methode hat Probleme mit zirkulären Abhängigkeiten. Weiterhin kann die Reihenfolge der Eigenschaften im geklonten Objekt unterschiedlich sein.,

# Flacher Klon vs tiefer Klon

Als ich spread ... zum Kopieren eines Objekts verwendete, erstelle ich nur eine flache Kopie. Wenn das Array verschachtelt oder mehrdimensional ist, funktioniert es nicht. Hier ist unser Beispiel, das wir verwenden werden:

# Flache Kopie

Klonen wir unser Objekt mit spread:

const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';

Also haben wir unser geklontes Objekt geändert, indem wir die Stadt geändert haben. Mal sehen, die Ausgabe.

console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱

Eine flache Kopie bedeutet, dass die erste Ebene kopiert und auf tiefere Ebenen verwiesen wird.,

# Deep Copy

Nehmen wir dasselbe Beispiel, aber das Anwenden einer Deep Copy mit „JSON“

Wie Sie sehen, ist die Deep copy eine echte Kopie für verschachtelte Objekte. Oft ist eine flache Kopie gut genug, Sie brauchen keine tiefe Kopie. Es ist wie eine Nagelpistole gegen einen Hammer. Die meiste Zeit ist der Hammer vollkommen in Ordnung. Mit einer Nagelpistole für einige kleine Kunst und Handwerk ist oft nur ein Overkill, ein Hammer ist in Ordnung. Es geht darum, das richtige Werkzeug für den richtigen Job zu verwenden 🤓

# Performance

Leider kann ich keinen Test für Spread schreiben, da er noch nicht offiziell in der Spezifikation enthalten ist., Trotzdem habe ich es in den Test aufgenommen, damit Sie es in Zukunft 😝ausführen können. Das Ergebnis zeigt jedoch, dass Object.assign viel schneller ist als JSON.

Leistungstest

# Community Input

# Objekt.weisen Sie vs Spread

@d9el zu: Es ist wichtig, dieses Objekt zu beachten.assign ist eine Funktion, die das Zielobjekt ändert und zurückgibt. In Samanthas Beispiel, das Folgendes verwendet,

const cloneFood = Object.assign({}, food);

{} ist das Objekt, das geändert wird., Das Zielobjekt wird zu diesem Zeitpunkt von keiner Variablen referenziert, aber da Object.assign das Zielobjekt zurückgibt, können wir das resultierende zugewiesene Objekt in der Variablen cloneFood speichern. Wir könnten unser Beispiel umstellen und Folgendes verwenden:

const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }

Offensichtlich ist der Wert von beef in unserem Lebensmittelobjekt falsch, sodass wir mit Object.assign den richtigen Wert von beefzuweisen können., Wir verwenden den zurückgegebenen Wert der Funktion überhaupt nicht, aber wir ändern unser Zielobjekt, auf das wir mit const .

Spread hingegen ist ein Operator, der Eigenschaften eines Objekts in ein neues Objekt kopiert., Wenn wir das obige Beispiel mit spread replizieren möchten, um unsere Variable zu ändern food...

const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'

... Wir erhalten einen Fehler, da wir spread beim Erstellen neuer Objekte verwenden und daher ein ganz neues Objekt zuweisen, das mit

deklariert wurde id=“453833e800″>

, was illegal ist., Wir können also entweder eine neue Variable deklarieren, in der sich unser neues Objekt befindet, wie folgt:

const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }

oder wir könnten mit let oder var deklarieren, wodurch wir ein ganz neues Objekt zuweisen können:

let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }

Danke: @d9el

# Deep Clone mit externen Bibliotheken

# Weitere Möglichkeiten zur Verwendung von JavaScript

  • @hariharan_d3v : Object.fromEntries(Object.entries(food)) klont das Objekt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.