Hoisting
JavaScript-Hoisting bezieht sich auf den Prozess, bei dem der Interpreter scheinbar die Deklaration von Funktionen, Variablen, Klassen oder Importen an den Anfang ihres Scopes verschiebt, bevor der Code ausgeführt wird.
Hoisting ist kein normativ definierter Begriff in der ECMAScript-Spezifikation. Die Spezifikation definiert eine Gruppe von Deklarationen als HoistableDeclaration, was jedoch nur die Deklarationen von function
, function*
, async function
und async function*
umfasst. Hoisting wird oft als eine Eigenschaft von var
-Deklarationen angesehen, wenn auch auf eine andere Weise. Im umgangssprachlichen Sinne können alle folgenden Verhaltensweisen als Hoisting angesehen werden:
- Die Möglichkeit, den Wert einer Variablen in ihrem Scope zu verwenden, bevor die Zeile erreicht wird, in der sie deklariert ist. ("Value hoisting")
- Die Möglichkeit, eine Variable in ihrem Scope zu referenzieren, bevor die Zeile erreicht wird, in der sie deklariert ist, ohne einen
ReferenceError
auszulösen, wobei der Wert immerundefined
ist. ("Declaration hoisting") - Die Deklaration der Variablen verursacht Verhaltensänderungen in ihrem Scope, bevor die Zeile, in der sie deklariert ist, erreicht wird.
- Die Nebeneffekte einer Deklaration treten auf, bevor der restliche Code ausgeführt wird, der sie enthält.
Die vier oben genannten Funktionsdeklarationen werden mit Verhalten vom Typ 1 gehoben; var
-Deklarationen werden mit Verhalten vom Typ 2 gehoben; let
, const
und class
-Deklarationen (auch zusammen als lexikalische Deklarationen bezeichnet) werden mit Verhalten vom Typ 3 gehoben; import
-Deklarationen werden mit Verhalten vom Typ 1 und Typ 4 gehoben.
Einige bevorzugen es, let
, const
und class
als nicht-hoisting zu betrachten, da die temporal dead zone jegliche Nutzung der Variablen vor ihrer Deklaration strikt verbietet. Diese Abweichung ist in Ordnung, da Hoisting kein universell akzeptierter Begriff ist. Allerdings kann die temporale Todeszone andere beobachtbare Änderungen in ihrem Scope verursachen, was darauf hindeutet, dass es irgendeine Form von Hoisting gibt:
const x = 1;
{
console.log(x); // ReferenceError
const x = 2;
}
Wenn die const x = 2
Deklaration überhaupt nicht gehoben wird (also erst wirksam wird, wenn sie ausgeführt wird), dann sollte die console.log(x)
-Anweisung in der Lage sein, den x
-Wert aus dem oberen Scope zu lesen. Da jedoch die const
-Deklaration den gesamten Scope, in dem sie definiert ist, "verunreinigt", liest die console.log(x)
-Anweisung den x
-Wert aus der const x = 2
-Deklaration, die noch nicht initialisiert ist, und löst einen ReferenceError
aus. Dennoch ist es möglicherweise nützlicher, lexikalische Deklarationen als nicht-hoisting zu charakterisieren, da aus praktischer Sicht das Hoisting dieser Deklarationen keine bedeutenden Eigenschaften mit sich bringt.
Beachten Sie, dass das Folgende keine Form von Hoisting ist:
{
var x = 1;
}
console.log(x); // 1
Hier gibt es kein "Zugriff vor Deklaration"; es liegt einfach daran, dass var
-Deklarationen nicht auf Blöcke begrenzt sind.
Weitere Informationen zum Hoisting finden Sie unter:
var
/let
/const
Hoisting — Grammatik und Typen-Leitfadenfunction
Hoisting — Funktionen-Leitfadenclass
Hoisting — Klassen-Leitfadenimport
Hoisting — JavaScript-Module