Javascript Pointer / Verrücktheit der Referenz. Kann jemand das erklären?
Javascript übergibt Objekte by reference. Das macht auch Sinn. Aber sobald Sie anfangen, die Manipulation dieser Objekte, alles wirkt in einer Weise, die scheinen unintuitiv. Lassen Sie mich ein Beispiel geben:
var a, b;
a = {}
b = a;
a['one'] = {};
console.log( JSON.stringify(a) );
//outputs: {"one":{}}
console.log( JSON.stringify(b) );
//outputs: {"one":{}}
Das ist ja alles schön und gut, weil jetzt b
hat einen Zeiger auf a
es ist also zu erwarten, dass die Zuordnung von Sachen zu a
wird auch Auswirkungen auf b
.
Aber dann, wenn ich dies tun:
a = a['one'];
console.log( JSON.stringify(a) );
//outputs: {}
console.log( JSON.stringify(b) );
//outputs: {"one":{}}
Dies ist für mich überraschend. Ich würde erwarten, dass a
und b
noch die gleichen (und werden {}
seit a['one']
vorher festgelegt wurde, um {}
und a
war a['one']
).
Aber das ist nicht der Fall. Es scheint, dass a
verliert seine Referenz zu b
wenn es zugeordnet ist, etwas neues, aber b
behält den Wert, der a
festgelegt wurde vor a
verlieren Ihren Bezug zu b
.
Aber dann, wenn ich dies tun:
a['two'] = 2;
console.log( JSON.stringify(a) );
//outputs: {"two":2}
console.log( JSON.stringify(b) );
//outputs: {"one":{"two":2}}
Was? a
hat klar verloren Verweis auf b
, aber b
scheint, haben noch einige Verweis auf a
.
Nicht das leere Objekt {}
Punkt an eine andere Stelle im Speicher, so dass jede variable, die darauf verweisen, zeigt jetzt auf den gleichen Platz?
Kann jemand mit einem festen Griff auf das, erklär es mir?
b
ist ein Zeiger auf a
" ist, wo die Unwahrheit beginnt. "jetzt b
Punkte auf derselben Stelle wie a
" ist der fix. a
zeigt an, indem Sie das verändert, was die zweite variable b
zeigt auf - was Sie definitiv nicht tun (ob in einer Funktion oder nicht). InformationsquelleAutor der Frage Philip Walton | 2011-11-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Folgenden deinem Beispiel Zeile für Zeile:
a
jetzt verweist das neue Objekt.b
jetzt verweist auf das gleiche Objekt, dassa
Referenzen. Beachten Sie, dass es nicht aufa
.Das neue Objekt hat nun einen index
'one'
, das auf ein anderes neues Objekt.Wenn Sie
Sind Sie
a
zu findena['one']
, die das neue Objekt, das Sie erstellt, wenn Sie habena['one'] = {}
.b
noch Referenzen das Objekt, das Sie erstellt mita = {}
.Du verwechselst das Problem, wenn Sie sagen "
a
verloren hat, seine Referenz zub
", weila
bezieht sich nicht aufb
, noch Umgekehrt.a
undb
siehe Objekte, und Sie können gemacht werden, um beziehen sich auf andere Objekte. Wie diese:Mit
a = {}; b = a
erhalten SieDann mit
a['one'] = {}
erhalten SieDann mit
a = a['one']
erhalten SieInformationsquelleAutor der Antwort Seth Carnegie
😛 Du bist Abstieg in die knitty gritty details und ich bin froh, dass Sie gefragt, wie Sie wird klüger sein, bis Ende.
Schauen Sie nicht in Bezug auf die Zeiger, da ich denke, dass ist immer, wo Sie verwirrt. Denke, dass es eher in Bezug auf den heap (oder einfach nur "Speicher", wenn man so will) und die symbol-Tabelle.
Können beginnen, indem Sie die ersten paar Zeilen von deinem code:
Was Sie getan haben, ist hier ein Objekt auf dem heap, und zwei Symbole auf das symbol Tabelle. Es sieht wie folgt aus:
Symbol Tabelle:
Heap:
.
Hier ist, wo die Dinge interessant: Objekte haben Ihre eigenen "symbol-Tabellen" (in der Regel sind diese nur hash-Tabellen, aber nannte es ein symbol-Tabelle kann deutlicher machen).
Nun, nach deiner nächsten Anweisung, haben Sie 3 Dinge zu berücksichtigen: Die Globale Symboltabelle
<object val 1>
's symbol-Tabelle und der heap.Ausführen die folgende Zeile ein:
Und Dinge die nun wie folgt Aussehen:
Globalen Symboltabelle:
<object val 1>
's Symbol-TabelleHeap:
.
Nun lief man den folgenden code:
Diese sollte hoffentlich scheint eine triviale änderung. Das Ergebnis ist:
Globalen Symboltabelle:
<object val 1>
's Symbol-TabelleHeap:
.
Folgenden Speicherplatz auf dem heap sollte hoffentlich klar machen, warum du die Ausgabe, die du hast.
Nun werden die Dinge sogar noch interessanter, weil Sie jetzt tun:
Ok, so lassen Sie uns dies Schritt für Schritt.
a
Punkte auf Speicherbereich0x400004
enthält<object val 2>
<object val 2>
ist ein leeres Objekt, also dessen symbol-Tabelle beginnt leer<object val 2>
's symbol-Tabelle.Wenn Sie nicht müde der Blick auf diese Diagramme noch nicht, werden Sie. Dinge, die nun wie folgt Aussehen:
Globalen Symboltabelle:
<object val 1>
's Symbol-Tabelle<object val 2>
's Symbol-TabelleHeap:
.
Wenn Ihr fleißig die Zeit zu nehmen, befolgen Sie die memory locations, Sie werden sehen, dass Ihre browser angezeigt, die richtige Ausgabe.
InformationsquelleAutor der Antwort riwalk
Denke, dass der anonyme Objekt als sich selbst mit einem Namen:
Der Schlüssel ist, sich daran zu erinnern, dass Variablen, die Verweise auf Objekte, keine Referenzen auf andere Variablen. Und das selbe Objekt bezeichnet werden kann von einer beliebigen Anzahl von Variablen.
InformationsquelleAutor der Antwort maerics
Objekte in Javascript bestehen kann durch sich selbst ohne einen Namen. Zum Beispiel:
wird eine neue Instanz des dictionary-Objekts.
erstellt ein neues dictionary-Objekt und macht
a
beziehen. Jetztmacht
b
beziehen sich auf dasselbe zugrunde liegende Objekt. Sie können danna
Punkt woanders:sowie
b
noch Punkte, um den gleichen dictionary-Objekt vor. Das Verhalten vonb
ist nicht, wie Sie ändern, wasa
Punkte zu.InformationsquelleAutor der Antwort Greg Hewgill
Soweit ich weiß ist Sie überschrieben eine also ich denke, die engine speichert es in einen anderen Speicherplatz, in der Erwägung, dass b noch auf die alte eine's Speicher-Adresse (die irgendwie nicht zerstört).
InformationsquelleAutor der Antwort R01010010