2017-11-21 2 views
0

Ich muss etwas falsch machen.ES6 Wie wird sichergestellt, dass aktualisierte Kloneigenschaften keine Auswirkungen auf das Original haben?

  1. Instantiate Klasse Person als Bob mit dem Namen 'Bob'
  2. Clone Bob als neue var Alice
  3. Rename Alice mit dem Namen 'Alice'
  4. Log Namen von Bob & Alice

Ich erwarte, dass Bobs Name 'Bob' bleibt, aber es wurde auf 'Alice' aktualisiert, obwohl Bob nicht aktualisiert wurde ...?

class Person { 
 
    constructor(attr) { 
 
    this.attr = attr; 
 
    } 
 

 
    talk() { 
 
    console.log('My name is ' + this.attr.name); 
 
    } 
 
} 
 

 
function clone(obj) { 
 
    return Object.assign(Object.create(Object.getPrototypeOf(obj)), obj); 
 
} 
 

 
var Bob = new Person({ 
 
    name: 'Bob' 
 
}); 
 

 
var Alice = clone(Bob); 
 
Alice.attr.name = 'Alice'; 
 

 
Alice.talk(); 
 
Bob.talk();

Vielen Dank im Voraus.

+0

Wie klonen Sie das Objekt? – Intervalia

+0

Sie klonten nur 'Bob'. Sie haben das Attr-Objekt nicht geklont. Speichern Sie Werte auf dem Objekt selbst, nicht in einem verschachtelten Objekt! – Bergi

Antwort

2

Object.assign führt eine flache Kopie, so Bob und Alice ihre eigene Kopie des attr Bezug haben, aber sie beziehen sich auf die gleiche verschachtelte Objekt. attr.name ist immer noch eine gemeinsame Zeichenfolge.

Sie benötigen einen tief (er) Kopie ausführen, oder auch neu zuweisen die attr Eigenschaft:

Alice.attr = { name: 'Alice' }; 
+0

Diese Einsicht ist perfekt. Vielen Dank! – blindmikey

+0

Klonen ist mehrdeutig, wenn es um benutzerdefinierte Objekte geht, die parent-ähnliche Referenzen oder zyklische Referenzen oder Funktionen haben, und Getter, die Nebenwirkungen haben, usw. Siehe zum Beispiel [diese Antwort gab ich einer tiefen Klonfrage] (https://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript/40294058#40294058). – trincot

1

Die einfachste Lösung für das Klonen ist:

var cloned = JSON.parse(JSON.stringify(objectToClone)); 

Aber es gibt einen Haken in diesem Lösung wird dies fehlschlagen, wenn der Attributwert Ihres Objekts eine Funktion ist.

var a = {name: 'a', exec: function() {return true;}}; 
var b = JSON.parse(JSON.stringify(a)); 
console.log(b); // {name: 'a'} 

für einen besseren Einblick über das Klonen, können Sie diesen Artikel verweisen: deep cloning

Verwandte Themen