Bereits in der Chrome-Konsole deklarierte Variablen werfen undefinierte Referenzfehler für let

8

Kürzlich stieß ich in der Chrome-Konsole auf dieses komische Ding. Hier weise ich absichtlich eine undefinierte Sache zu, um einen Fehler zu erzeugen.

%Vor%

Als ich dann versuchte, etwas zu legitimieren, passierte das:

%Vor%

Ich kann also nicht "let" verwenden, weil a bereits deklariert wurde. Also habe ich versucht, etwas anderes dem "bereits erklärten a" zuzuordnen.

%Vor%

Es scheint also so, als ob ich etwas anderem nicht wieder zuweisen kann, aber gleichzeitig wurde erklärt, dass ich es nicht wieder verwenden darf.

Ich verstehe den Unterschied zwischen dem Deklarieren und dem Zuweisen einer Variablen. Aber hier scheint es, dass keiner von beiden wieder getan werden könnte. Hat das etwas mit dem Umfang von "Let" in der Konsole zu tun? Weil das gleiche für "var" völlig funktioniert.

%Vor%

Follow-up

Es scheint einen gewissen Unterschied zwischen dem "manuellen" Heben der Let-Anweisung und dem impliziten Fall zu geben.

%Vor%

, während in diesem Fall Beispiel erneut zugewiesen werden kann.

%Vor%     
whales 21.12.2016, 04:26
quelle

2 Antworten

6

Dies geschieht, wenn Sie die temporäre Totzone in den globalen Bereich einbeziehen. Wie Sie vielleicht wissen, werden let -Deklarationen gehisst, aber nicht initialisiert . Aufgrund des Kontrollflusses kann es vorkommen, dass eine Variable niemals initialisiert wird:

%Vor%

Das ist in einem Funktionsumfang gut. Vielleicht ist etwas schiefgelaufen, vielleicht wurde die Variable gar nicht benötigt - beim nächsten Aufruf wird ein neuer Bereich mit einer neuen Variable erstellt.

Eine ähnliche Sache kann im globalen Gültigkeitsbereich passieren, wenn Sie eine Exception auslösen, bevor die Variable initialisiert wird (nur Exceptions funktionieren hier als Kontrollflusskonstrukt, nichts anderes erreicht den gleichen Effekt).

%Vor%

Im Gegensatz zum Funktionsumfang ist es hier wichtig, dass die Variable nicht initialisiert bleibt. Der globale Gültigkeitsbereich gilt für immer und die Variable ist ewig tot . Es wurde nicht und wird nie initialisiert, und lexikalische Variablen können nicht erneut deklariert werden (was zur Vermeidung von Fehlern beiträgt).

Diese wurde auf es-discuss diskutiert , aber als irrelevant erachtet. Wenn die Ausführung von <script> auf oberster Ebene einen Fehler auslöst, haben Sie größere Probleme als nicht initialisierte Variablen. Es gibt keinen Pfad zum Wiederherstellen. Wenn Sie eine benötigen (z. B. indem Sie versuchen, sie in aufeinanderfolgenden Skripten erneut zu deklarieren), müssen Sie trotzdem var verwenden.

Dass Sie das selbe Problem in der Devtools-Konsole haben, ist ein bisschen lästig, aber könnte für die Konsole als spezieller Bereich gelöst werden.

    
Bergi 21.12.2016, 06:03
quelle
1

Sie sollten wissen, in JS zu hissen. Grundsätzlich eine solche Erklärung let a = werwr;

wird als interpretiert let a; a = werwr;

Und das ist, warum a bereits deklariert ist, wenn Sie Ihre zweite Codezeile ausführen.

AKTUALISIEREN

Es gibt also einen HINWEIS in den ES-Spezifikationen Ссылка

  Die Deklarationen

let und const definieren Variablen, die auf die   Ausführen der LexicalEnvironment des Ausführungskontexts Die Variablen sind   erstellt, wenn ihre Lexikalische Umgebung instanziiert wird aber   darf nicht in irgendeiner Weise zugegriffen werden, bis die Variable LexicalBinding ist   evaluiert . Eine Variable, die durch ein LexicalBinding mit einem Initialisierer definiert wird   erhält den Wert des AssignmentExpression seines Initializers   Die LexicalBinding wird ausgewertet, nicht wenn die Variable erstellt wird. Ob   Eine LexicalBinding in einer let-Deklaration hat keinen Initialisierer   Der Variable wird beim LexicalBinding der Wert undefined zugewiesen   wird ausgewertet.

...

"Es kann jedoch nicht auf irgendeinen Zugriff zugegriffen werden, bis die LexicalBinding der Variablen" ausgewertet wird Dies bedeutet, dass die Deklaration erfolgreich abgeschlossen werden muss, bevor Sie auf die Variable zugreifen können (entweder Wert abrufen, Wert zuweisen oder typeof ausführen, oder Ereignis delete );

In Ihrem Fall wird die LexicalBinding der Variablen durch die Ausnahme unterbrochen.

%Vor%

Bitte folgen Sie dem Link und lesen Sie mehr darüber. Wenn Sie einen Weg finden, um a wiederherzustellen, bitte sagen Sie mir. Danke, heute habe ich etwas neues über Javascript herausgefunden.

    
vothaison 21.12.2016 04:30
quelle