Was ist das Ergebnis dieses JavaScript-Code-Snippets und warum?

9

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:

%Vor%

Nach meinem derzeitigen Kenntnisstand entspricht a.x = a = {n:2}; :

%Vor%

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.

    
Lisa 27.02.2018, 03:20
quelle

4 Antworten

7

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:

%Vor%

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:

%Vor%

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:

  1. Sei lref das Ergebnis der Auswertung von LeftHandSideExpression.
  2. Sei rref das Ergebnis der Evaluierung von AssignmentExpression.

Dies zeigt deutlich, dass die linke Seite einer Zuweisung ausgewertet wird bevor die rechte Seite ausgewertet wird.

    
JLRishe 27.02.2018 03:51
quelle
1

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.

    
Sterling Archer 27.02.2018 03:35
quelle
0

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.

    
Code of God 27.02.2018 03:51
quelle
0

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ändert

Der 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?

    
Naga Sai A 27.02.2018 03:34
quelle

Tags und Links