Hoisting

JavaScript Hoisting bezieht sich auf den Prozess, bei dem der Interpreter den Anschein erweckt, als würde er die Deklaration von Funktionen, Variablen, Klassen oder Importen an den Anfang ihres Scopes verschieben, 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, aber diese umfasst nur die Deklarationen von function, function*, async function und async function*. Hoisting wird oft auch als Eigenschaft von var-Deklarationen betrachtet, jedoch auf andere Weise. Im umgangssprachlichen Gebrauch können alle der folgenden Verhaltensweisen als Hoisting angesehen werden:

  1. Die Möglichkeit, den Wert einer Variable in ihrem Scope zu verwenden, bevor die Zeile deklariert ist. ("Wert-Hoisting")
  2. Die Möglichkeit, eine Variable in ihrem Scope zu referenzieren, bevor die Zeile deklariert ist, ohne einen ReferenceError auszulösen, aber der Wert ist immer undefined. ("Deklarations-Hoisting")
  3. Die Deklaration der Variable verursacht Verhaltensänderungen in ihrem Scope, bevor die Zeile deklariert ist.
  4. Die Nebeneffekte einer Deklaration werden erzeugt, bevor der Rest des Codes, der sie enthält, ausgewertet wird.

Die vier obigen Funktionsdeklarationen werden mit Verhaltenstyp 1 gehoben; var-Deklaration wird mit Verhaltenstyp 2 gehoben; let, const und class-Deklarationen (auch zusammenfassend als lexikalische Deklarationen bekannt) werden mit Verhaltenstyp 3 gehoben; import-Deklarationen werden mit Verhaltenstyp 1 und Typ 4 gehoben.

Einige ziehen es vor, let, const und class als nicht-hoisting zu betrachten, da die temporal dead zone jede Verwendung der Variable vor ihrer Deklaration strikt verbietet. Diese Dissenz ist in Ordnung, da Hoisting kein allgemein anerkannter Begriff ist. Dennoch kann die temporal dead zone andere beobachtbare Änderungen in ihrem Scope verursachen, was darauf hindeutet, dass es eine Form von Hoisting gibt:

js
const x = 1;
{
  console.log(x); // ReferenceError
  const x = 2;
}

Wenn die const x = 2-Deklaration überhaupt nicht gehoben wird (wie in, sie tritt nur in Kraft, wenn sie ausgeführt wird), dann sollte die console.log(x)-Anweisung in der Lage sein, den x-Wert vom oberen Scope zu lesen. Da jedoch die const-Deklaration immer noch den gesamten Scope, in dem sie definiert ist, "verunreinigt", liest die console.log(x)-Anweisung das x aus der const x = 2-Deklaration, die noch nicht initialisiert ist, und löst einen ReferenceError aus. Trotzdem könnte es nützlicher sein, lexikalische Deklarationen als nicht-hoisting zu charakterisieren, da aus einer utilitaristischen Perspektive das Hoisting dieser Deklarationen keine bedeutenden Merkmale bringt.

Beachten Sie, dass das Folgende keine Form von Hoisting ist:

js
{
  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 beschränkt sind.

Für weitere Informationen über Hoisting, siehe:

Siehe auch