Ich bin ein Newby von JavaScript und habe gerade diese Frage beantwortet. Ich kann es nicht herausfinden, indem ich auf Stackoverflow google und suche. Code-Snippet ist wie folgt:
Nach meinem derzeitigen Kenntnisstand entspricht a.x = a = {n:2};
:
Was schließlich zu {n:2, x:{n:2}}
führt. So sollte a.x
gleich {n:2}
sein, und weil b = a
, also b.x = {n:2}
.
Aber das Ergebnis, das ich im Browser ausführe ist: alert(a.x)
ist undefined
und alert(b.x)
ist [object object]
.
Kann jemand erklären warum? vielen Dank.
Dies ist eine Frage der Priorität des Operators, und die Angelegenheit besteht darin, dass drei Operatoren hier involviert sind: =
, =
und .
.
.
hat eine höhere Priorität als =
, was bedeutet, dass a.x
ausgewertet wird, bevor die Zuweisungen stattfinden. Danach kann die Zuweisung von a
mid-Anweisung den Wert von a
im Ausdruck a.x
nicht beeinflussen, da es bereits ausgewertet wurde.
Wir können dies mit dem folgenden Code beobachten:
Was wir hier sehen können, ist, dass auf den Getter von a
im Prozess der Anweisung, auf die wir gerade sprechen, vor zugegriffen wird und dass nur einmal darauf zugegriffen wird. Dies zeigt uns, dass a.x
vor a.x = ....
ausgewertet wird .
Wo du falsch liegst, ist, dass diese Aussage tatsächlich so auswertet:
%Vor% Mit anderen Worten, der Bezeichner a
ist "gebunden", bevor die Anweisung ausgeführt wird, und die Eigenschaftenreferenzen verweisen auf diesen gebundenen Wert für die Dauer der Anweisung.
In diesem Fall ist [the value that a referred to before the statement started executing]
äquivalent zu b
, aber es entspricht nicht dem neuen Wert von a
. Deshalb hat b.x
einen Wert und a.x
nicht.
Man könnte sagen, dass der Prozess so funktioniert:
und das ergibt das gleiche Ergebnis wie Ihr ursprünglicher Code.
Die ECMAScript-Spezifikation legt das Verfahren zur Bewertung von AssignmentExpression der Form LeftHandSideExpression = AssignmentExpression . Die ersten beiden Schritte sind:
Dies zeigt deutlich, dass die linke Seite einer Zuweisung ausgewertet wird bevor die rechte Seite ausgewertet wird.
Sie sind auf etwas gestoßen, das operator precedence/associativity
genannt wird.
Betrachten Sie ihr Beispiel:
%Vor%mit dem erwarteten Ergebnis, dass a und b den Wert 5 erhalten. Dies ist, weil Der Zuweisungsoperator gibt den zugewiesenen Wert zurück. Zuerst, b wird auf 5 gesetzt. Dann wird das a auch auf 5 gesetzt, der Rückgabewert von b = 5, aka rechter Operand des Auftrags.
Dies zerfällt zu:
%Vor%Zerlegt sich in:
%Vor%Da b ein Verweis auf a ist, wird es nach der Zuweisung geändert.
Der Code
%Vor%ist dasselbe wie
%Vor%Beide Variablen a und b werden auf 1 gesetzt;
Jetzt, da Sie mit einem Objekt arbeiten und sich selbst einen Wert zuweisen (Sie würden tatsächlich eine Schleife erstellen, aber nicht desto weniger wird die Routine in JS verwirrt (was es sollte).
Grundsätzlich ist das Problem die Reihenfolge der Auswertung.
Das ist nur meine Meinung, nachdem ich damit experimentiert habe. Ich würde gerne hören, welche anderen Antworten die Community hat.
a.x in diesem Szenario ist nicht definiert, weil
Eine Referenz in a.x wurde aufgrund der zweiten Zuweisung (a = {n: 2})
in einen neuen Referenzwert geändertDer Wert der Eigenschaft mit alter Referenz ist nicht definiert, da sie geändert wurde
Um Unterschiede zu sehen, fügen Sie eine neue Eigenschaft hinzu, etwa so
a.x = a.y = {n: 2} // Dies ändert nicht die Referenz von a
%Vor%Weitere Details aus der ähnlichen Frage hier - Wie funktioniert ax = a = {n: b} in JavaScript?
Tags und Links javascript