var a = {}
var b = {}
try{
a.x.y = b.e = 1 // Uncaught TypeError: Cannot set property 'y' of undefined
} catch(err) {
console.error(err);
}
console.log(b.e) // 1
var a = {}
var b = {}
try {
a.x.y.z = b.e = 1 // Uncaught TypeError: Cannot read property 'y' of undefined
} catch(err) {
console.error(err);
}
console.log(b.e) // undefined
javascript
operators
order-of-execution
Kevin Askin
quelle
quelle
b.z = 1
undb.e = 1
zuerst ausführen (bei gegebener Rechtsassoziativität=
), danna.x.y.z = ...
ausführen und fehlschlagen; Warum besteht dieb
Aufgabe in einem Fall, in dem anderen jedoch nicht?y
nicht existierta.x
; aber das ist in beiden Fällen wahr. Warum verhindert es die Zuordnung auf der rechten Seite im zweiten Fall, aber nicht im ersten? Was ist anders in der Reihenfolge der Ausführung? (Ich erwähnte Syntaxfehler, weil das Timing des Syntaxfehlers sich stark von dem eines Laufzeitfehlers unterscheidet.)Antworten:
Wenn Sie die Fehlermeldung richtig lesen, werfen Fall 1 und Fall 2 unterschiedliche Fehler auf.
Fall
a.x.y
:Fall
a.x.y.z
:Ich denke, es ist am besten, es durch schrittweise Ausführung in einfachem Englisch zu beschreiben.
Fall 1
Fall 2
In den Kommentaren, Solomon Tam fanden diese ECMA Dokumentation über Zuweisungsoperation .
quelle
Die Reihenfolge der Operationen ist klarer, wenn Sie den Komma-Operator in der Klammer-Notation ausnutzen, um zu sehen, welche Teile ausgeführt werden, wenn:
Betrachtet man die Spezifikation :
PutValue
ist das, was das wirftTypeError
:Einer Eigenschaft von kann nichts zugewiesen werden
undefined
- die[[CanPut]]
interne Methode vonundefined
wird immer zurückgegebenfalse
.Mit anderen Worten: parst der Dolmetscher auf die linke Seite, analysiert dann die rechte Seite, dann wirft einen Fehler , wenn die Eigenschaft auf der linken Seite nicht zugeordnet werden können.
Wenn Sie das tun
Die linke Seite wird erfolgreich analysiert , bis sie
PutValue
aufgerufen wird. Die Tatsache, dass die.x
Eigenschaft bewertet wird,undefined
wird erst berücksichtigt, nachdem die rechte Seite analysiert wurde. Der Interpreter sieht es als "Weisen Sie der Eigenschaft" y "von undefined einen Wert zu und weisen Sie einer Eigenschaft zu, dieundefined
nur Würfe enthältPutValue
.Im Gegensatz:
Der Interpreter kommt nie an den Punkt, an dem er versucht, der
z
Eigenschaft zuzuweisen , da er zuersta.x.y
in einen Wert aufgelöst werden muss. Wenn esa.x.y
auf einen Wert (sogar aufundefined
) aufgelöst würde, wäre es in Ordnung - ein Fehler würdePutValue
wie oben hineingeworfen . Der Zugriffa.x.y
löst jedoch einen Fehler aus, da auf die Eigenschafty
nicht zugegriffen werden kannundefined
.quelle
Betrachten Sie den folgenden Code:
Die grobe Übersicht über die Schritte erforderlich um den Code auszuführen ist wie folgt ref :
a.x.y
eine Referenz Ref bestehend aus Grundwerta.x
(nicht definiert) und referenzierten name (y
).y
undefined auf den Wert. Dies soll eine TypeError-Ausnahme ref auslösen .quelle