2016-05-06 25 views
1

Ich arbeitete an einem Ereignis Widget und seltsames Verhalten gefunden, es kann Noob Frage sein.Javascript Zuordnung Operator seltsames Verhalten

Im Folgenden finden Sie Codeblock I wurde auf

var event={0:{competition:{like:false}}} 
console.log(event[0].competition.like); //returns false 
var cmpt=event[0].competition; 
cmpt.like=true; 
console.log(event[0].competition.like) //returns true 

arbeiten Können Sie mir helfen, zu verstehen, warum Wert von Attribute [wie] des Wettbewerbs innerhalb -Ereignisobjekts wird immer aktualisiert. und wie kann ich dies verhindern und nicht aktualisiert Ereignisobjekt?

Ich versuchte in google/so zu suchen, aber diese Fragen adressierten verschiedene Probleme.

+0

Sie kopieren nur einen Verweis, nicht das Objekt. –

+1

Es ist, weil in JavaScript Objekte durch Verweis übergeben werden, damit es funktioniert, wie Sie möchten, müssen Sie das Wettbewerbsobjekt klonen. – jcubic

+1

Wenn es sich nicht um eine Zeichenfolge oder eine Zahl handelt, handelt es sich um eine Referenz (Zeiger). Um ein Objekt zu kopieren (statt auf es zu zeigen), wird 'Object.create (event [0] .competition)' – slebetman

Antwort

3

Können Sie mir helfen, zu verstehen, warum Wert des Attributs [wie] von Wettbewerb innerhalb Ereignisobjekt

Sie die Referenz kopiert immer aktualisiert: Sie können diese _.clone() method from lodash library mit zum Beispiel tun von event[0].competition in cmpt durch diese Zuordnung.

Nun zeigt cmpt auf dasselbe Objekt, auf das event[0].competition zeigt. Wenn Sie also den Wert aktualisieren, werden im Grunde genommen Änderungen an demselben Objekt vorgenommen, auf das beide Variablen zeigen.

Wie kann ich dies verhindern und nicht aktualisiert Ereignisobjekt?

Wenn Sie wollen sicherstellen, dass ältere Werte sollten nicht dann Sie tief-Klon müssen, um das Objekt aktualisiert, während

Zuweisung

ersetzen

var cmpt=event[0].competition; 

mit

var cmpt=JSON.parse(JSON.stringify(event[0].competition)); 
+0

Vielen Dank. Ich benutzte jQuery.clone, um Objekt in neue Variable zu kopieren. – Ravi

1

Sie zuweisen Bezug auf

event[0].competition 

variable cmpt und dann ändern Sie es Wert ist - was auch immer Sie mit Original-Instanz tun die cmpt Variable auch

1

In JavaScript-Objekte betreffen, werden immer als Referenz übergeben . Dies bedeutet, dass wenn Sie ein Objekt einer anderen Variablen zuweisen, es immer noch auf dasselbe Objekt zeigt. Wenn Sie zwei separate Objekte haben wollen, müssen Sie sie klonen.

var cmpt = _.clone(event[0].competition); 
1

Wenn Sie ein Objekt haben und es wie ein neues Objekt kopieren und das neue Objekt ändern, wird das alte Objekt aktualisiert.

Dies ist, weil Sie nicht eigentlich sind es zu kopieren, haben Sie gerade einen anderen Verweis auf das ursprüngliche Objekt, also was auch immer Sie auf der ‚Kopie‘ zu ändern in der ursprünglichen widerspiegelt ...

1

Dies liegt daran, Wenn Sie in JavaScript einen Objektwert einer anderen Variablen zuweisen, weisen Sie ihm tatsächlich einen Wert zu (er wird nicht kopiert, wie primitive Werte).

so beziehen sich'cmpt' und'event [0] .competition 'auf das gleiche Objekt.

Wenn Sie das Objekt klonen müssen und es nur primitive Werte, Arrays und einfache Objekte (keine Funktionen) enthält, können Sie'JSON.stringify' und'JSON.parse' verwenden.

1

Warum Sie das Ereignis nur "umbenennen", können Sie so tun.

var event={0:{competition:{like:false}}} 
console.log(event[0].competition.like); //returns false 
var cmpt = {}; 
cmpt.like = event[0].competition.like; 
cmpt.like = true; 
console.log(event[0].competition.like) //returns false 
1

können Sie verwenden, um das folgende:

var event={0:{competition:{like:false}}} 
console.log(event[0].competition.like); //returns false 
var cmpt=jQuery.extend({}, event[0].competition); 
cmpt.like=true; 
console.log(event[0].competition.like) //returns false (changed) 
1

und wie kann ich das und nicht mehr aktualisiert Ereignisobjekt verhindern?

können Sie Object.create() mit ersten Parameter null gesetzt verwenden; Iterieren event[0].competition Eigenschaften bei value der Eigenschaft Deskriptoren bei zweiten Parameter Object.create(), Einstellung Wert jeder Eigenschaft zu null, zurückgegeben neu erstellt Objekt mit Eigenschaften von event[0].competition auf null festgelegt.

var event = { 
 
    0: { 
 
    competition: { 
 
     like: false 
 
    } 
 
    } 
 
} 
 

 
console.log(event[0].competition.like); //returns false 
 

 
var cmpt = Object.create(null, { 
 
    competition: { 
 
    value: (function(obj) { 
 
     var _obj = {}; 
 
     for (var prop in obj) { 
 
     _obj[prop] = null 
 
     }; 
 
     return _obj 
 
    }(event[0].competition)), 
 
    writable: true, 
 
    enumerable: true, 
 
    configurable: true 
 
    } 
 
}); 
 
cmpt.competition.like = true; 
 
console.log(event[0].competition.like, cmpt.competition.like 
 
      , event[0], cmpt) //`false, `true`