Wenn du schon etwas über JavaScript gelernt hast, hast du vielleicht schon gesehen, dass Variablen manchmal innerhalb einer Funktion oder Schleife deklariert werden. Aber sind diese Variablen auch außerhalb des Codes, in dem sie erstellt wurden, sichtbar? Das hängt von der Sichtbarkeit der Variablen ab, auch bekannt als “variable scope”. Es gibt grundsätzlich zwei Arten von scopes: der functional scope und der block scope.
Functional Scope
Variablen, die mit dem Schlüsselwort var
deklariert werden, haben einen functional scope. Das bedeutet, dass sie innerhalb der gesamten Funktion sichtbar sind, in der sie deklariert wurden, einschließlich aller Funktionen, die innerhalb dieser Funktion definiert wurden. Allerdings sind sie außerhalb dieser Funktion nicht sichtbar.
Beispiel:
function testingScope1() {
var condition = true;
var myVarMessage = "Hallo var!";
if (condition) {
console.log(myVarMessage); // "Hallo var!"
}
}
console.log(myVarMessage); // Fehler: undefiniert
Variablen können in einem untergeordneten Scope erneut deklariert werden, was dazu führt, dass die ursprüngliche Variable überschrieben wird. Dies kann zu unerwartetem Verhalten führen.
Beispiel:
var myVar = 'außerhalb';
if (true) {
var myVar = 'innerhalb';
console.log(myVar); // Ausgabe: "innerhalb"
}
console.log(myVar); // Ausgabe: "innerhalb"
Aus diesem Grund wird seit ES6 empfohlen, anstelle von var
besser const
oder let
zu verwenden, da sie beide einen block scope haben.
Block Scope
Seit ECMAScript 6 (ES6) unterstützt JavaScript nativ block scope-Variablen. Das heißt, Variablen, die mit den Schlüsselwörtern let
und const
deklariert werden, sind nur innerhalb des Blocks sichtbar, in dem sie definiert wurden. Ein “Block” ist der Bereich innerhalb einer if-Bedingung, einer for- oder while-Schleife und einer switch-Anweisung. Praktisch alles, was zwischen geschweiften Klammern {}
steht, ist ein Block.
Beispiel:
function testingScope3() {
if (true) {
var myVar = 'Ich bin ein var';
const myConst = 'Ich bin ein const';
let myLet = 'Ich bin ein let';
}
console.log(myVar); // Ausgabe: "Ich bin ein var"
console.log(myConst); // Fehler: myConst ist nicht definiert
console.log(myLet); // Fehler: myLet ist nicht definiert
}
testingScope3();
Es ist auch möglich, einer Variablen im block scope mit let
eine neue Zuweisung zuzuweisen, wodurch der ursprüngliche Wert überschrieben wird – aber nur innerhalb des Blocks der neuen Variablen.
Beispiel:
let myLet = 'außerhalb';
if (true) {
let myLet = 'innerhalb';
console.log(myLet); // Ausgabe: "innerhalb"
}
console.log(myLet); // Ausgabe: "außerhalb"
Lexical Scope
Der Scope von untergeordneten Funktionen hat immer Zugriff auf die Variablen im übergeordneten Scope. Dieses Konzept nennt man “lexical scope”.
Beispiel:
function testingScope() {
var myConstMessage = "Hallo const!";
function innerFunction() {
console.log(myConstMessage);
}
innerFunction(); // Ausgabe: "Hallo const!"
}
Hoisting
JavaScript-Deklarationen von var
und Funktionen werden zum Anfang ihres jeweiligen Scopes “hochgezogen” (hoisted). Das bedeutet, dass sie verwendet werden können, bevor sie tatsächlich deklariert wurden.
Beispiel:
x = 5;
console.log(x); // Ausgabe: 5
var x;
Aber Vorsicht: Nur die Deklarationen werden hoisted, nicht die Initialisierung.
Beispiel:
console.log(y); // Ausgabe: undefined
var y = 7;
console.log(y); // Ausgabe: 7
Das erste console.log
gibt zwar keinen Fehler aus, da die Variable dank des hoisting bereits deklariert ist. Aber die Initialisierung fehlt noch.
Zwei Hinweise:
- Viele Entwickler sind sich des hoisting-Verhaltens nicht bewusst und das kann zu unerwarteten Fehlern führen. Es wird daher empfohlen, Deklarationen immer zu Beginn des Scopes festzulegen (was JavaScript ohnehin am Ende des Scopes macht).
- Im “strict mode” (
use strict
) erlaubt JavaScript keine Verwendung von Variablen, bevor sie deklariert wurden.
Jetzt kennst du die Grundlagen der Sichtbarkeit von Variablen in JavaScript. Verwende dieses Wissen, um deine Codes effektiv und fehlerfrei zu schreiben!