618 Stimmen

Wie klont man ein Array von Objekten in JavaScript?

...wo jedes Objekt auch Verweise auf andere Objekte innerhalb desselben Arrays hat?

Als ich zum ersten Mal mit diesem Problem konfrontiert wurde, dachte ich nur an etwas wie

var clonedNodesArray = nodesArray.clone()

existieren würde, und suchte nach Informationen darüber, wie man Objekte in JavaScript klont. Ich habe gefunden eine Frage auf Stack Overflow (beantwortet von demselben @JohnResig) und er wies darauf hin, dass man mit jQuery Folgendes tun kann

var clonedNodesArray = jQuery.extend({}, nodesArray);

um ein Objekt zu klonen. Ich habe dies jedoch ausprobiert, und es werden nur die Referenzen der Objekte im Array kopiert. Wenn ich also

nodesArray[0].value = "red"
clonedNodesArray[0].value = "green"

wird der Wert sowohl von nodesArray[0] als auch von clonedNodesArray[0] "grün" sein. Dann habe ich versucht

var clonedNodesArray = jQuery.extend(true, {}, nodesArray);

das ein Objekt tief kopiert, aber ich bekomme " zu viel Rekursion " und " Kontrollstapelüberlauf " Nachrichten von beiden Firebug y Oper Libelle beziehungsweise.

Wie würden Sie das machen? Ist das etwas, das gar nicht gemacht werden sollte? Gibt es eine wiederverwendbare Möglichkeit, dies in JavaScript zu tun?

4voto

nebulae Punkte 2645

Mein Ansatz:

var temp = { arr : originalArray };
var obj = $.extend(true, {}, temp);
return obj.arr;

gibt mir einen schönen, sauberen, tiefen Klon des ursprünglichen Arrays - ohne dass eines der Objekte auf das Original zurückverweist :-)

4voto

Stef Punkte 2463

JQuery extend funktioniert einwandfrei. Sie müssen nur angeben, dass Sie ein Array klonen und nicht ein Objekt ( beachten Sie die [] anstelle von {} als Parameter für die extend-Methode ):

var clonedNodesArray = jQuery.extend([], nodesArray);

3voto

Brett Zamir Punkte 13189

Dadurch werden Arrays, Objekte, Null- und andere skalare Werte tief kopiert, und es werden auch alle Eigenschaften von nicht-nativen Funktionen tief kopiert (was ziemlich selten vorkommt, aber möglich ist). (Aus Effizienzgründen versuchen wir nicht, nicht-numerische Eigenschaften von Arrays zu kopieren).

function deepClone (item) {
  if (Array.isArray(item)) {
    var newArr = [];
    for (var i = item.length; i-- > 0;) {
      newArr[i] = deepClone(item[i]);
    }
    return newArr;
  }
  if (typeof item === 'function' && !(/\(\) \{ \[native/).test(item.toString())) {
    var obj;
    eval('obj = '+ item.toString());
    for (var k in item) {
      obj[k] = deepClone(item[k]);
    }
    return obj;
  }
  if (item && typeof item === 'object') {
    var obj = {};
    for (var k in item) {
      obj[k] = deepClone(item[k]);
    }
    return obj;
  }
  return item;
}

3voto

Bijay Rai Punkte 951

In JavaScript ändern Array- und Objektkopien die ursprünglichen Werte, so dass eine tief Kopie ist die Lösung für dieses Problem.

Eine tiefe Kopie bedeutet, dass ein neues Array erstellt und die Werte kopiert werden, denn was auch immer mit diesem Array geschieht, es wird niemals das ursprüngliche Array beeinflussen.

JSON.parse y JSON.stringify ist der beste und einfachste Weg, um tief kopieren. Die JSON.stringify() Methode wandelt einen JavaScript-Wert in eine JSON-Zeichenkette um. JSON.parse() Methode analysiert eine JSON-Zeichenkette und konstruiert den JavaScript-Wert oder das Objekt, das durch die Zeichenkette beschrieben wird.

Tiefes Klonen

let a = [{ x:{z:1} , y: 2}];
let b = JSON.parse(JSON.stringify(a));
b[0].x.z=0

console.log(JSON.stringify(a)); //[{"x":{"z":1},"y":2}]
console.log(JSON.stringify(b)); // [{"x":{"z":0},"y":2}]

Für weitere Informationen: Hier lesen

3voto

markt Punkte 4979

Array.slice kann verwendet werden, um ein Array oder einen Teil eines Arrays zu kopieren...

Dies würde mit Zeichenketten und Zahlen arbeiten .. - Ändern einer Zeichenfolge in einem Array würde nicht die andere beeinflussen - aber Objekte sind immer noch nur durch Verweis kopiert, so dass Änderungen an referenzierten Objekten in einem Array eine Auswirkung auf das andere Array haben würde.

Hier ist ein Beispiel für einen JavaScript-Rückgängigmachungs-Manager, der dafür nützlich sein könnte: http://www.ridgway.co.za/archive/2007/11/07/simple-javascript-undo-manager-for-dtos.aspx

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