Wenn Sie Objekte als Parameter übergeben, übergibt JavaScript diese als Referenz und macht es schwierig, lokale Kopien der Objekte zu erstellen.
var o = {}; (function(x){ var obj = x; obj.foo = 'foo'; obj.bar = 'bar'; })(o)
o
wird haben.foo
und.bar
.Es ist möglich, dies durch Klonen zu umgehen. einfaches Beispiel:
var o = {}; function Clone(x) { for(p in x) this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p]; } (function(x){ var obj = new Clone(x); obj.foo = 'foo'; obj.bar = 'bar'; })(o)
o
wird nicht haben.foo
oder.bar
.
Frage
- Gibt es eine bessere Möglichkeit, Objekte nach Wert zu übergeben, als eine lokale Kopie / einen lokalen Klon zu erstellen?
javascript
vol7ron
quelle
quelle
Antworten:
Nicht wirklich.
Je nachdem, was Sie tatsächlich benötigen, besteht eine Möglichkeit darin,
o
den Prototyp eines neuen Objekts festzulegen.Eigenschaften, die Sie hinzufügen,
obj
werden also nicht hinzugefügto
. Alle Eigenschaften, dieobj
mit demselben Eigenschaftsnamen wie eine Eigenschaft in hinzugefügt wurden,o
schattieren dieo
Eigenschaft.Natürlich sind alle hinzugefügten Eigenschaften
o
verfügbar,obj
wenn sie nicht schattiert sind, und alle Objekteo
in der Prototypenkette werden mit denselben Aktualisierungen verseheno
.Wenn
obj
eine Eigenschaft vorhanden ist, die auf ein anderes Objekt verweist, z. B. ein Array, müssen Sie sicherstellen, dass Sie dieses Objekt schattieren, bevor Sie dem Objekt Elemente hinzufügen. Andernfalls werden diese Elemente hinzugefügtobj
und von allen Objekten gemeinsam genutzt, die dies tun habenobj
in der Prototypkette.Hier können Sie sehen , dass , weil Sie nicht das Array an Schatten haben
baz
aufo
mit einerbaz
Eigenschaft aufobj
, dieo.baz
wird Array geändert.Stattdessen müssen Sie es zuerst beschatten:
quelle
Object.create
in meiner Antwort vorschlagen , aber ich wollte mich nicht darauf beschränken, die Oberflächlichkeit der Kopie zu erklären ;-)var obj = new Object(x)
. Für mich würde ich denken, dassnew Object(x)
diesObject.create(x)
standardmäßig - interessantnew Object(x)
spuckt einfach das gleiche Objekt zurück (wie du wahrscheinlich bemerkt hast) . Es wäre schön, wenn es eine native Möglichkeit zum Klonen gäbe. Ich bin mir nicht sicher, ob etwas in Arbeit ist.Überprüfen Sie diese Antwort https://stackoverflow.com/a/5344074/746491 .
Kurz gesagt,
JSON.parse(JSON.stringify(obj))
ist eine schnelle Möglichkeit, Ihre Objekte zu kopieren, wenn Ihre Objekte in json serialisiert werden können.quelle
JSON
nicht enthalten sind und definiert werden müssen - könnte genauso gut mit einem Namen wie beschrieben werdenClone
. Ich vermute jedoch, dass sich meine Meinung in Zukunft ändern könnte, da JSON stärker in nicht browserbasierte Software wie Datenbanken und IDEs integriert istHier ist die Klonfunktion, die eine tiefe Kopie des Objekts ausführt:
Jetzt können Sie wie folgt verwenden:
quelle
Verwenden
Object.assign()
Beispiel:
Ein saubereres Beispiel, das dasselbe tut:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
quelle
var b = Object.assign({}, a);
a
werden als Referenz kopiert.Sie sind etwas verwirrt darüber, wie Objekte in JavaScript funktionieren. Die Objektreferenz ist der Wert der Variablen. Es gibt keinen unserialisierten Wert. Wenn Sie ein Objekt erstellen, wird seine Struktur im Speicher gespeichert und die Variable, der es zugewiesen wurde, enthält einen Verweis auf diese Struktur.
Selbst wenn das, was Sie fragen, in einem einfachen, muttersprachlichen Konstrukt bereitgestellt würde, wäre es technisch immer noch Klonen.
JavaScript ist wirklich nur ein Wert, der übergeben wird. Es ist nur so, dass der übergebene Wert möglicherweise auf etwas verweist.
quelle
Benutze das
x
undx1
wird zwei verschiedene Objekte sein, Änderung inx
wird sich nicht ändernx1
quelle
Javascript wird immer als Wert übergeben. In diesem Fall wird eine Kopie der Referenz
o
an die anonyme Funktion übergeben. Der Code verwendet eine Kopie der Referenz, mutiert jedoch das einzelne Objekt. Es gibt keine Möglichkeit, Javascript an etwas anderem als dem Wert vorbeizulassen.In diesem Fall möchten Sie eine Kopie des zugrunde liegenden Objekts übergeben. Das Klonen des Objekts ist der einzige Rückgriff. Ihre Klonmethode muss jedoch ein wenig aktualisiert werden
quelle
In Anbetracht der jQuery-Benutzer gibt es auch eine Möglichkeit, dies mithilfe des Frameworks auf einfache Weise zu tun. Nur eine andere Art, wie jQuery unser Leben ein wenig einfacher macht.
Verweise :
quelle
Tatsächlich wird Javascript immer als Wert übergeben . Da Objektreferenzen jedoch Werte sind , verhalten sich Objekte so, als würden sie als Referenz übergeben .
Um dies zu umgehen , stringifizieren Sie das Objekt und analysieren Sie es zurück, beide mit JSON. Siehe Codebeispiel unten:
quelle
use obj2 = {... obj1} Jetzt haben beide Objekte den gleichen Wert und haben unterschiedliche Referenzen
quelle
let a = {value: "old"}
let b = [...a]
b.value = "new"
und a sein wird{value: "old"}
, b sein wird{value: "new"}
. Aber es klappt nicht, wannlet a = [{value: "old"}]
let b = [...a]
b[0].value = "new"
und a sein wird[{value: "new"}]
, b sein wird[{value: "new"}]
.Ich musste ein Objekt nach Wert (nicht als Referenz) kopieren und fand diese Seite hilfreich:
Was ist der effizienteste Weg, um ein Objekt in JavaScript tief zu klonen? . Insbesondere das Klonen eines Objekts mit dem folgenden Code von John Resig:
quelle
Mit der ES6-Syntax:
let obj = Object.assign({}, o);
quelle
Object.assign
ist, dass es keine tiefe Kopie ausführt.Wenn Sie sich darauf beschränken, ist es nur ein ausgefallener, übermäßig komplizierter Proxy, aber vielleicht könnte Catch-All Proxies das tun?
quelle
Wenn Sie lodash oder verwenden
npm
, verwenden Sie die Zusammenführungsfunktion von lodash, um alle Eigenschaften des Objekts wie folgt in ein neues leeres Objekt zu kopieren:var objectCopy = lodash.merge({}, originalObject);
https://lodash.com/docs#merge
https://www.npmjs.com/package/lodash.merge
quelle