2015-12-19 3 views
9

In diesem Beitrag, Multiple left-hand assignment with JavaScript, @Crescent Fresh sagt JavsScript linken Zuordnung ist rechts assoziativ. Aber der folgende Code erscheint mir es richtig associativeness bricht:Multiple Links-Zuweisung mit JavaScript, wirklich richtig assoziativ?

var a = {n: 1}; 
a.x = a = {n: 2}; 
console.log(a.x);// undefined 

Kann mir jemand erklären, warum a.x nicht definiert ist?

Edit: Das obige Snippet soll "richtige Assoziativität" testen, in der realen Welt bitte nicht ähnlichen Code schreiben.

+0

Circular Verweis, 'a.x = a' – Tushar

+0

@Tushar Nein, versuchen Sie es selbst in Chrom-Konsole. –

+0

@ 尤慕 李 Die erste Anweisung 'ax = a' wird entfernt/überschrieben durch' a = {n: 2}; ' – Tushar

Antwort

4

tl; dr - JS ermittelt, wo der Wert vor dem Berechnen des Werts angegeben werden soll, und ein Nebeneffekt des Berechnens dieses Werts ändert den Wert a.


Siehe die spec for simple assignment.

Schritt 1 ist "Lass lref das Ergebnis der Auswertung von LeftHandSideExpression sein."

Schritt 2 ist "Lassen Sie Rref das Ergebnis der Auswertung AssignmentExpression sein."

Das erste, was passiert, ist, dass eine Eigenschaft x für das Objekt erstellt wird, das in a gespeichert ist (wobei n 1 ist).

Dann wird die rechte Seite ausgewertet (was schließlich a mit einem neuen Objekt überschreibt, wobei n 2 ist).

Dann wird das Ergebnis dieses Ausdrucks (das Objekt, wobei n 2 ist) x auf dem ursprünglichen Objekt zugewiesen (wobei n 1 ist).

Sie können dies mit in der Tat sehen:

"use strict"; 
 
var a = {n: 1}; 
 
var b = a; 
 

 
a.x = a = {n: 2}; 
 

 
console.log(a); 
 
console.log(b);

+0

Die Antworten von @JLRishe und Quentin sind beide korrekt, aber stackoverflow erlaubt nur eine Antwort zu akzeptieren :(. Ich habe beide gewählt und akzeptiert, weil eine Antwort mit Spezifikationsreferenzierung fester und überzeugender ist. Danke, Sir. –

+0

Für js ** reference **, hier ist ein toller Artikel [Warum ist (0, obj.prop)() kein Methodenaufruf] (http://www.2ality.com/2015/12/references.html) von Dr. Axel Rauschmayer –

7

Es ist richtig assoziativ. Es ist einfach, dass der Bezeichner a an eine Referenz gebunden ist, bevor die Anweisung ausgeführt wird.

Wir können dies bezeugen mit dem folgenden:

var a, b; 
a = b = { n: 1 }; 
a.x = a = {n: 2}; // a.x refers to the x property of the value a references 
        //  before this statement executes 
console.log(a); // {n: 2} 
console.log(b); // {n: 1, x: {n: 2}} 

Wenn = assoziativen gelassen wurden, b.x ein kreisförmiger Rückbezug auf b wären nach der dritten Zeile ausführt, ist es aber nicht.


Kann mir jemand erklären, warum a.x nicht definiert ist?

Ja, das ist es, was, wenn die Leitung a.x = a = {n: 2} ausführt geschieht: auf die Variable a

  • Der Wert der x Eigenschaft des Objekts zugeordnet ist

    1. Der Wert {n: 2} zugeordnet {n: 2} dass a bezogen auf vor der Ausführung der Anweisung.

    Nichts wird die x Eigenschaft a ‚s neuen Wertes zugewiesen. Deshalb ist a.xundefined.

  • 0

    in Java-Script-Objekte werden als Referenz übergeben um. Sie werden niemals kopiert.

    var a = {n:1} 
    

    so früher a hat Referenz eines Objekts, das eine Eigenschaft aufweist, n = 1

    auf zweite Anweisung a.x = a = {n:2} ax eine Eigenschaft x auf vorhergehenden Objekt, dessen Wert hinzugefügt hat, ist ein Objekt mit Eigenschafts n = 2 dieselbe Anweisung zuweisen die Referenz des neuen Objekts.

    +0

    Javascript beachten Sie keinen Platz zwischen Java und Skript – Jonathan