@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 letoder constnicht 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/ classDeklarationen ist die Initialisierung .
Erstere werden mit undefinedoder 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 ReferenceErrorAusnahme 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 undefinedlike 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 letund constin dieser Angelegenheit?
Nein, sie funktionieren genauso, was das Heben betrifft. Der einzige Unterschied zwischen ihnen besteht darin, dass eine constAmeise nur im Initialisierungsteil der Deklaration zugewiesen werden muss und kann ( const one = 1;beide const one;und spätere Neuzuweisungen wie one = 2sind ungültig).
1: varDeklarationen 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.