@thefourtheye sagt zu Recht, dass auf diese Variablen nicht zugegriffen werden kann, bevor sie deklariert wurden. Es ist jedoch etwas komplizierter.
Werden Variablen mit deklariert let
oder const
nicht gehisst? Was ist hier wirklich los?
Alle Erklärungen ( var
, let
, const
, function
, function*
, class
) werden als "hochgezogen" in JavaScript. Dies bedeutet, dass, wenn ein Name in einem Bereich deklariert ist, der Bezeichner in diesem Bereich immer auf diese bestimmte Variable verweist:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Dies gilt sowohl für Funktions- als auch für Blockbereiche 1 .
Der Unterschied zwischen var
/ function
/ function*
Deklarationen und let
/ const
/ class
Deklarationen ist die Initialisierung .
Erstere werden mit undefined
oder mit der (Generator-) Funktion initialisiert, sobald die Bindung oben im Bereich erstellt wird. Die lexikalisch deklarierten Variablen bleiben jedoch nicht initialisiert . Dies bedeutet, dass eine ReferenceError
Ausnahme ausgelöst wird, wenn Sie versuchen, darauf zuzugreifen. Es wird nur initialisiert, wenn die let
/ const
/ class
-Anweisung ausgewertet wird, alles vor (oben), was als zeitliche Totzone bezeichnet wird .
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Beachten Sie, dass eine let y;
Anweisung die Variable mit undefined
like initialisiert let y = undefined;
.
Die zeitliche Totzone ist kein syntaktischer Ort, sondern die Zeit zwischen der Erstellung der Variablen (Bereich) und der Initialisierung. Es ist kein Fehler, auf die Variable im Code über der Deklaration zu verweisen, solange dieser Code nicht ausgeführt wird (z. B. ein Funktionskörper oder einfach toter Code), und es wird eine Ausnahme ausgelöst, wenn Sie vor der Initialisierung auf die Variable zugreifen, auch wenn der Zugriff erfolgt Code befindet sich unterhalb der Deklaration (z. B. in einer zu früh aufgerufenen angehobenen Funktionsdeklaration).
Gibt es einen Unterschied zwischen let
und const
in dieser Angelegenheit?
Nein, sie funktionieren genauso, was das Heben betrifft. Der einzige Unterschied zwischen ihnen besteht darin, dass eine const
Ameise nur im Initialisierungsteil der Deklaration zugewiesen werden muss und kann ( const one = 1;
beide const one;
und spätere Neuzuweisungen wie one = 2
sind ungültig).
1: var
Deklarationen funktionieren natürlich immer noch nur auf Funktionsebene
let foo = () => bar; let bar = 'bar'; foo();
illustriert, dass alle Deklarationen noch besser gehisst werden , weil es aufgrund der zeitlichen Totzone nicht offensichtlich ist.