Lexical Scope in JavaScript
Note: This post is from my old blog and thus written in German and potentially obsolete.
Im Zusammenhang mit Funktionen und Closures in JavaScript fällt auch immer wieder der Begriff des lexikalischen Gültigkeitsbereiches (lexical scope).
Stoyan Stefanov erklärt in seinem Buch “Object-Oriented JavaScript” kurz aber verständlich was es damit auf sich hat: Funktionen erzeugen ihren Gültigkeitsbereich zum Zeitpunkt ihrer Definition, und nicht zum Zeitpunkt ihrer Ausführung. Man spricht daher auch von einem statischen Gültigkeitsbereich.
Hier ein Beispiel um dies greifbarer zu machen:
function funktionA() {
var a = 1;
funktionB();
}
function funktionB() {
console.log(a);
}
funktionA(); // "a is not defined"
Innerhalb von funktionA
befindet sich sowohl die Variable a
als auch ein Aufruf der funktionB
. Von daher könnte man evtl. annehmen, dass funktionB
Zugriff auf a
hat. Das ist hier jedoch nicht der Fall, wie die Ausgabe der Konsole zeigt.
Wenn eine Funktion definiert wird, merkt sie sich sozusagen ihre Umgebung. Diese besteht aus ihrem lokalen Gültigkeitsbereich, sowie der Gültigkeitsbereiche all ihrer Eltern. Also aller Funktionen, innerhalb derer sie ggf. definiert wurde. Außerdem haben Funktionen Zugriff auf den globalen Gültigkeitsbereich (global scope). Somit existiert eine Kette von Gültigkeitsbereichen (scope chain).
In JavaScript durchlaufen Funktionen genau diese Kette beim Suchen nach einer Variablen. Deshalb konnte funktionB
in obigem Beispiel auch keine Variable a
finden, denn zum Zeitpunkt ihrer Definition befand sich keine Variable diesen Namens in der entsprechenden Kette von Gültigkeitsbereichen.
Anders wäre dies bei einem dynamischen Gültigkeitsbereich. Da dieser in JavaScript nicht verwendet wird, obwohl with
und eval
einen gewissen Sonderstatus einnehmen (siehe hierzu den Artikel von Dmitry Soshnikov), gehe ich hier nicht weiter darauf ein.