Es ist wichtig zu verstehen, was der =Operator in JavaScript tut und was nicht.
Der =Betreiber erstellt keine Kopie der Daten.
Der =Bediener erstellt einen neuen Verweis auf dieselben Daten.
Nachdem Sie Ihren ursprünglichen Code ausgeführt haben:
var a = $('#some_hidden_var').val(),
b = a;
aund bsind jetzt zwei verschiedene Namen für das gleiche Objekt .
Jede Änderung, die Sie am Inhalt dieses Objekts vornehmen, wird identisch angezeigt, unabhängig davon, ob Sie über die aVariable oder die referenzierenb Variable darauf . Sie sind das gleiche Objekt.
Wenn Sie später versuchen, mit diesem Code bzum ursprünglichen aObjekt "zurückzukehren" :
b = a;
Der Code macht eigentlich gar nichts , weil aund bgenau das gleiche sind. Der Code ist der gleiche, als hätten Sie geschrieben:
b = b;
was offensichtlich nichts tun wird.
Warum funktioniert Ihr neuer Code?
b = { key1: a.key1, key2: a.key2 };
Hier erstellen Sie ein brandneues Objekt mit dem {...}Objektliteral. Dieses neue Objekt ist nicht dasselbe wie Ihr altes Objekt. Sie stellen jetzt einb als Referenz auf dieses neue Objekt, das macht, was Sie wollen.
Um ein beliebiges Objekt zu verarbeiten, können Sie eine Objektklonfunktion wie die in Armands Antwort aufgeführte verwenden oder, da Sie jQuery verwenden, einfach die $.extend()Funktion verwenden . Diese Funktion erstellt entweder eine flache oder eine tiefe Kopie eines Objekts. (Verwechseln Sie dies nicht mit der $().clone()Methode zum Kopieren von DOM-Elementen, nicht von Objekten.)
Für eine flache Kopie:
b = $.extend( {}, a );
Oder eine tiefe Kopie:
b = $.extend( true, {}, a );
Was ist der Unterschied zwischen einer flachen und einer tiefen Kopie? Eine flache Kopie ähnelt Ihrem Code, der ein neues Objekt mit einem Objektliteral erstellt. Es wird ein neues Objekt der obersten Ebene erstellt, das Verweise auf dieselben Eigenschaften wie das ursprüngliche Objekt enthält.
Wenn Ihr Objekt nur primitive Typen wie Zahlen und Zeichenfolgen enthält, tun eine tiefe und eine flache Kopie genau dasselbe. Wenn Ihr Objekt jedoch andere darin verschachtelte Objekte oder Arrays enthält, kopiert eine flache Kopie diese verschachtelten Objekte nicht, sondern erstellt lediglich Verweise auf sie. Sie könnten also das gleiche Problem mit verschachtelten Objekten haben wie mit Ihrem Objekt der obersten Ebene. Zum Beispiel bei diesem Objekt:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
Wenn Sie eine flache Kopie dieses Objekts erstellen, ist die xEigenschaft Ihres neuen Objekts dasselbe xObjekt wie das Original:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
Jetzt sehen Ihre Objekte folgendermaßen aus:
// copy looks as expected
var copy = {
w: 321,
x: {
y: 654,
z: 789
}
};
// But changing copy.x.y also changed obj.x.y!
var obj = {
w: 123, // changing copy.w didn't affect obj.w
x: {
y: 654, // changing copy.x.y also changed obj.x.y
z: 789
}
};
Sie können dies mit einer tiefen Kopie vermeiden. Die tiefe Kopie wird in jedes verschachtelte Objekt und Array (und Datum in Armands Code) zurückgeführt, um Kopien dieser Objekte auf dieselbe Weise zu erstellen, wie sie eine Kopie des Objekts der obersten Ebene erstellt hat. Änderungen copy.x.ywürden sich also nicht auswirken obj.x.y.
Kurze Antwort: Im Zweifelsfall möchten Sie wahrscheinlich eine tiefe Kopie.
awurde, gehe.val()ich davon aus, dass es sich um JSON (eine Zeichenfolge) und nicht um ein Objekt handelt - stimmt das? Verwenden SieJSON.parse(a)irgendwann, um ein tatsächliches Objekt zu erhalten?