2016-04-19 2 views
11

Das folgende ist ein Beispielszenario, das ich für meine eigene Praxis dieses Problems ausarbeitete. Wenn Sie direkt zu den technischen Details springen möchten, lesen Sie bitte "Technische Details" unten.Wann muss die Object.assign() -Methode verwendet werden, um eine Instanz eines Objekts zu kopieren?

Ich habe ein persönliches Projekt, an dem ich gearbeitet habe, um JavaScript zu lernen. Grundsätzlich kann der Benutzer einen Schuh entwerfen, indem er verfügbare Optionen auswählt.

Der Trick ist, dass der linke und rechte Schuh unter anderen Eigenschaften die gleiche Größe haben müssen, aber Dinge wie Farbe, Schuhspitze Textur, etc. können unabhängige Eigenschaften pro Schuh sein. (Ich dachte, das wäre eine gute Möglichkeit für mich, Objektmanipulation und Vererbung zu üben).

Der Benutzer beginnt mit der Gestaltung des richtigen Schuhs; Wenn der "Swap" -Button angeklickt wird, um den linken Schuh zu betrachten, sieht der Benutzer derzeit eine Kopie des rechten Schuhs (aber umgekehrt). Nur beim ersten Tausch der Schuhe wird der linke Schuh erzeugt und eine exakte Kopie des rechten Schuhs angefertigt. Ab diesem Zeitpunkt bleiben einzigartige Optionen für die Schuhorientierung erhalten. Dann, wenn der Benutzer bestimmte Änderungen an das linke Schuhmodell vornimmt und dann zum richtigen Schuh wechselt, soll der Benutzer genau den richtigen Schuh sehen, den er ursprünglich entworfen hatte, bevor er auf den "Tauschen" -Button geklickt hat .

Wenn also ihr rechter Schuh rote Schnürsenkel hat, wechseln sie in die linke Schuhansicht und machen den linken Schuh eine blaue Spitze, dann sollte der Benutzer beim Zurückschalten auf den rechten Schuh rote Schnürsenkel sehen!


Technische Daten

Als ich den Code für mein Hauptprojekt schreibe ich in Schwierigkeiten mit den einzigartigen Möglichkeiten laufen perserved werden. Wenn ich zum Beispiel die Schnürsenkel für den linken Schuh grün machen würde, hätte der rechte Schuh immer grüne Schnürsenkel. Die Problembehandlung war einfach, denn nur wenn der richtige Schuh verloren ging, war es eine einzigartige Option, wie zum Beispiel eine rote Spitze, als ich die Spitzenfarbe für den linken Schuh einstellte.

console.log("THE RIGHT LACE BEFORE: " + rightShoe.laceId); 
leftShoe.laceId = 'green'; 
console.log("THE RIGHT LACE AFTER: " + rightShoe.laceId); 

Was an der Konsole anmelden würde, war:

RECHTS SPITZE DER VOR: rot

DIE RICHTIGE SPITZE NACH: grün

Auch wenn ich nicht veränderte Die rightShoe, wurde geändert, wann immer ich die leftShoe Eigenschaft änderte.

Also ging ich zurück, wo ich das leftShoe Objekt zunächst definieren, was ist, wenn der Benutzer klickt „swap“ zum ersten Mal im Leben des Skripts (Mein Amateur Gedanken war, warum propagieren und füllen Sie das leftShoe Objekt, wenn Der Benutzer passt möglicherweise nie den linken Schuh? Vielleicht ist es unnötig mit Daten geizig, ich weiß es nicht). Von nun an, habe ich nie die leftShoe als Kopie von rightShoe oder umgekehrt definiert. Ich stellte fest, dass ich auf die Tatsache, dass ich wahrscheinlich Objektreferenzierung aufhängte, auflegte, und wie bei anderen Sprachen änderte ich die Referenznummer und nicht den Wert.

Bevor ich mit meinen Problemen zu SO kam, wollte ich ein JSFiddle machen, um das Problem neu zu erstellen. Da mein Projekt langwierig ist (etwa 1500 Zeilen, einschließlich einiger THREE.js für Grafiken), habe ich mein Bestes getan, um den Prozess zu emulieren. Und so here it is.

Außer der JSFiddle arbeitete genau so, wie ich es erwartet hatte! Das linke Modell hat sein eindeutiges Attribut und seinen Datensatz für dieses Attribut beibehalten. Also habe ich ein wenig mehr gegraben und über die Object.assign() Methode gelesen. Also in meinem ursprünglichen Projektcode (nicht die Geige), änderte ich dies:

leftShoe = rightShoe; 

dazu:

leftShoe = Object.assign({}, rightShoe); 

So begeistert ich endlich bekommen haben bin, dies zu arbeiten, ich bin genauso amüsiert und verblüfft, weil ich nicht verstehe, warum mein JSFiddle nicht die assign()-Methode brauchte, aber mein identischer Projektcode. Vielen Dank.

+0

Im ersten Fall verweisen beide Variablen auf dasselbe Objekt. Im zweiten Fall erstellen Sie ein neues Objekt ('{}') und kopieren alle Eigenschaften mit 'Object.assign'. Das Mutieren eines Objekts spiegelt sich nicht in dem anderen wider. – Bergi

+0

@Bergi Danke, ich denke das macht jetzt Sinn für mich. Ziemlich Standard mit anderen Sprachen. Aber was mich jetzt abwirft, ist mein JSFiddle. Wenn Sie sich bitte meine Referenz-Zuordnung in Zeile 35 der Fiddle-I-Verknüpfung ansehen, werden Sie feststellen, dass die Werte für die linke Option unabhängig davon geändert werden, dass es sich um ein referenziertes Objekt handelt. – 8protons

+0

Ihre Geige ist verwirrend (mit all diesen currentChoice und leftChoiceExists), und wahrscheinlich haben Sie sich verwirrt. Nach der Zuweisung können Sie sehen, dass 'rightChoice.id' ==' leftChoice.id' - weil beide Variablen auf das gleiche Objekt beziehen. – Bergi

Antwort

8

Object.Assign erstellt eine neue Kopie des linken Schuhs, einschließlich aller aufzählbaren OWN-Eigenschaften. Wenn Sie leftshoe = rightshoe verwenden, machen Sie einen Bezug auf den linken Schuh. Ein Verweis verweist auf dasselbe Objekt, nicht auf ein NEUES COPY. Wenn Sie also eine Eigenschaft der Referenz ändern, ändert sich das Original tatsächlich, wie Sie festgestellt haben.

+1

Danke! Ich muss also fragen, warum ist das bei meinem JSFiddle nicht der Fall, mit dem ich verbunden bin? Ich nutze die Referenzzuordnung und kann dennoch Änderungen vornehmen. Sieh Dir die Zeile 35 meiner Fiddle an und gehe dann durch die Buttons, die ich gemacht habe, während ich die Ausgabe ansehe. – 8protons

+0

Die Geige scheint mir gebrochen zu sein. rightId wird auf 444 gesetzt, wenn es 999 bleiben soll –

Verwandte Themen