3750 Stimmen

Wie kann ich ein JavaScript-Objekt korrekt klonen?

Ich habe ein Objekt x . Ich würde es gerne als Objekt kopieren y , so dass Änderungen an y nicht verändern x . Ich habe festgestellt, dass das Kopieren von Objekten, die von integrierten JavaScript-Objekten abgeleitet sind, zu zusätzlichen, unerwünschten Eigenschaften führt. Das ist kein Problem, da ich eines meiner eigenen, wörtlich konstruierten Objekte kopiere.

Wie kann ich ein JavaScript-Objekt korrekt klonen?

35 Stimmen

0 Stimmen

Unterstützen Sie auf jeden Fall @Niyaz! Shortlink: tinyurl.com/JSCopyObject

290 Stimmen

Für JSON verwende ich mObj=JSON.parse(JSON.stringify(jsonObject));

62voto

Mohsen Alyafei Punkte 3573

Aktualisierung 06. Juli 2020

Es gibt drei (3) Möglichkeiten, Objekte in JavaScript zu klonen. Da es sich bei Objekten in JavaScript um Referenzwerte handelt, können Sie sie nicht einfach mit = kopieren.

Die Wege sind:

const food = { food: 'apple', drink: 'milk' }

// 1. Using the "Spread"
// ------------------

{ ...food }

// 2. Using "Object.assign"
// ------------------

Object.assign({}, food)

// 3. "JSON"
// ------------------

JSON.parse(JSON.stringify(food))

// RESULT:
// { food: 'apple', drink: 'milk' }

Dies kann als Referenzzusammenfassung verwendet werden.

0 Stimmen

Und welche neuen/einzigartigen Informationen ergeben sich daraus für diese Frage?

10 Stimmen

El JSON Ansatz würde alle Methoden des Objekts entfernen

3 Stimmen

Eine Zeichenkette aus einem Objekt zu erstellen und dann diese Zeichenkette in ein anderes Objekt zu parsen, nur um das Objekt zu kopieren, ist eine Art Monty Python'scher Programmierstil :-D

47voto

Kris Walker Punkte 897

Eine besonders unelegante Lösung ist die Verwendung der JSON-Kodierung, um Kopien von Objekten zu erstellen, die keine Mitgliedsmethoden haben. Die Methode besteht darin, das Zielobjekt in JSON zu kodieren und dann durch Dekodierung die gewünschte Kopie zu erhalten. Sie können so oft dekodieren, wie Sie wollen, um so viele Kopien wie nötig zu erstellen.

Natürlich gehören Funktionen nicht in JSON, so dass dies nur bei Objekten ohne Membermethoden funktioniert.

Diese Methode war perfekt für meinen Anwendungsfall, da ich JSON-Blobs in einem Key-Value-Speicher speichere, und wenn sie als Objekte in einer JavaScript-API offengelegt werden, enthält jedes Objekt tatsächlich eine Kopie des ursprünglichen Zustands des Objekts, sodass wir das Delta berechnen können, nachdem der Aufrufer das offengelegte Objekt verändert hat.

var object1 = {key:"value"};
var object2 = object1;

object2 = JSON.stringify(object1);
object2 = JSON.parse(object2);

object2.key = "a change";
console.log(object1);// returns value

0 Stimmen

Warum gehören Funktionen nicht zu JSON? Ich habe sie mehr als einmal als JSON übertragen gesehen...

6 Stimmen

Funktionen sind nicht Teil der JSON-Spezifikation, da sie keine sichere (oder intelligente) Methode zur Datenübertragung darstellen, wofür JSON eigentlich gedacht ist. Ich weiß, dass der systemeigene JSON-Encoder in Firefox Funktionen, die ihm übergeben werden, einfach ignoriert, aber ich bin mir über das Verhalten anderer nicht sicher.

1 Stimmen

@mark: { 'foo': function() { return 1; } } ist ein literal-konstruiertes Objekt.

43voto

musemind Punkte 927

Sie können einfach eine Streueigenschaft um ein Objekt ohne Referenzen zu kopieren. Aber Vorsicht (siehe Kommentare), die "Kopie" erfolgt nur auf der untersten Objekt-/Array-Ebene. Verschachtelte Eigenschaften sind immer noch Referenzen!


Vollständiger Klon:

let x = {a: 'value1'}
let x2 = {...x}

// => mutate without references:

x2.a = 'value2'
console.log(x.a)    // => 'value1'

Klonen mit Referenzen auf der zweiten Ebene:

const y = {a: {b: 'value3'}}
const y2 = {...y}

// => nested object is still a references:

y2.a.b = 'value4'
console.log(y.a.b)    // => 'value4'

JavaScript unterstützt von Haus aus keine tiefen Klone. Verwenden Sie eine Hilfsfunktion. Zum Beispiel Ramda:

http://ramdajs.com/docs/#clone

1 Stimmen

Das funktioniert nicht... es würde wahrscheinlich funktionieren, wenn x ein Array ist, zum Beispiel x= [ 'ab','cd',...]

4 Stimmen

Dies funktioniert, aber bedenken Sie, dass es sich um eine SHALLOW-Kopie handelt, d.h. alle tiefen Verweise auf andere Objekte bleiben Verweise!

0 Stimmen

Auf diese Weise kann auch ein Teilklon entstehen: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

40voto

Pavan Garre Punkte 2441
const objClone = { ...obj };

Beachten Sie, dass geschachtelte Objekte werden noch kopiert als Referenz.

2 Stimmen

Danke für den Hinweis, dass verschachtelte Objekte weiterhin als Referenz kopiert werden! Ich wurde fast verrückt, als ich meinen Code debuggte, weil ich verschachtelte Eigenschaften auf dem "Klon" änderte, aber das Original wurde geändert.

0 Stimmen

Dies ist ES2016, nicht 2018, und diese Antwort wurde gegeben zwei Jahre zuvor .

0 Stimmen

Was also, wenn ich auch eine Kopie der verschachtelten Eigenschaft haben möchte?

30voto

Calvin Punkte 4471

Aus diesem Artikel: Wie man Arrays und Objekte in Javascript kopiert von Brian Huisman:

Object.prototype.clone = function() {
  var newObj = (this instanceof Array) ? [] : {};
  for (var i in this) {
    if (i == 'clone') continue;
    if (this[i] && typeof this[i] == "object") {
      newObj[i] = this[i].clone();
    } else newObj[i] = this[i]
  } return newObj;
};

4 Stimmen

Das ist nahe dran, funktioniert aber nicht für jedes Objekt. Versuchen Sie, ein Date-Objekt mit dieser Methode zu klonen. Nicht alle Eigenschaften sind aufzählbar, so dass sie nicht alle in der for/in-Schleife auftauchen werden.

0 Stimmen

Hinzufügen zum Objekt-Prototyp wie dies brach jQuery für mich. Auch wenn ich umbenannt in clone2.

3 Stimmen

@iPadDeveloper2011 Der obige Code hatte einen Fehler, bei dem eine globale Variable namens 'i' '(for i in this)' erstellt wurde, anstatt '(for var i in this)'. Ich habe genug Karma, um ihn zu bearbeiten und zu korrigieren, also habe ich es getan.

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