Читать книгу JavaScript – Das Handbuch für die Praxis - David Flanagan - Страница 67
3.10.2Variablendeklarationen mit var
ОглавлениеIn JavaScript-Versionen vor ES6 können Variablen nur mit dem var-Schlüsselwort deklariert werden – und Konstanten lassen sich überhaupt nicht deklarieren. Die Syntax von var entspricht genau der von let:
var x;
var data = [], count = data.length;
for(var i = 0; i < count; i++) console.log(data[i]);
Obwohl var und let die gleiche Syntax aufweisen, unterscheiden sie sich deutlich in ihrer Funktionsweise:
Variablen, die mit var deklariert sind, haben keinen blockbezogenen Geltungsbereich. Stattdessen ist dieser auf den Funktionskörper beschränkt, in dem sie enthalten sind, egal wie tief die Deklarationen innerhalb dieser Funktion verschachtelt sind.
Wenn Sie var außerhalb eines Funktionskörpers verwenden, deklariert diese Anweisung eine globale Variable. Es gibt einen wichtigen Unterschied zwischen globalen Variablen, die mit var, und solchen, die mit let deklariert werden. Mit var deklarierte globale Variablen sind als Eigenschaften des globalen Objekts implementiert (siehe 3.7). Das globale Objekt kann als globalThis referenziert werden. Wenn Sie also var x = 2; außerhalb einer Funktion schreiben, entspricht dies einer Deklaration globalThis.x = 2;. Allerdings gibt es einen Unterschied: Die mit der globalen var-Deklaration erzeugten Eigenschaften können nicht mit dem delete-Operator gelöscht werden (siehe 4.13.4). Globale Variablen und Konstanten, die mit let und const deklariert werden, sind dagegen keine Eigenschaften des globalen Objekts.
Im Gegensatz zu let dürfen Variablen mit var mehrfach deklariert werden. Und weil var-Variablen einen funktionsbezogenen Geltungsbereich anstelle eines blockbezogenen aufweisen, ist es auch durchaus üblich, solche Neudeklarationen vorzunehmen. Die Variable i wird häufig für ganzzahlige Werte verwendet, insbesondere als Indexvariable in for-Schleifen. In einer Funktion mit mehreren for-Schleifen ist es typisch, dass jede einzelne mit for(var i = 0; … beginnt. Da var den Geltungsbereich nicht auf den Schleifenkörper eingrenzt, deklariert und initialisiert jede dieser Schleifen die gleiche Variable (gefahrlos) neu.
Eines der ungewöhnlichsten Merkmale von var-Deklarationen wird als Hoisting bezeichnet. Wenn eine Variable mit var deklariert wird, wird die Deklaration an die Spitze der umschließenden Funktion gehoben (oder »gehievt«). Die Initialisierung der Variablen findet zwar weiter dort im Code statt, wo die entsprechende Anweisung tatsächlich steht, die Definition der Variablen rückt aber an den Anfang der Funktion. Mit var deklarierte Variablen können deshalb überall in der umschließenden Funktion verwendet werden, ohne dass ein Fehler auftritt. Wenn der Initialisierungscode noch nicht ausgeführt wurde, mag der Wert der Variablen zwar undefined lauten, aber es löst keinen Fehler aus, wenn Sie die Variable vor deren Initialisierung verwenden. (Allerdings kann das wiederum zu Programmierfehlern führen und ist insofern eine ungünstige Verhaltensweise, die let korrigiert: Wenn Sie eine Variable mit let deklarieren und versuchen, diese zu benutzen, bevor die let-Anweisung ausgeführt wurde, führt das tatsächlich zu einem Fehler und nicht nur zu einem undefined-Wert der Variablen.)
Verwendung nicht deklarierter Variablen Sollten Sie im strict-Modus (siehe 5.6.3) versuchen, eine nicht deklarierte Variable zu verwenden, führt das zu einem Referenzfehler. Wenn Sie außerhalb des strict-Modus jedoch einem Namen, der nicht mit let, const oder var deklariert wurde, einen Wert zuweisen, erzeugen Sie eine neue globale Variable. Das gilt unabhängig davon, wie tief verschachtelt in Funktionen und Blöcken Ihr Code auch stehen mag. Das geschieht dann mit ziemlicher Sicherheit ungewollt, zieht Fehler nach sich und ist damit einer der besten Gründe dafür, den strict-Modus zu verwenden! | |
Globale Variablen, die auf diese unbeabsichtigte Weise erzeugt werden, verhalten sich genauso wie globale Variablen, die mit var deklariert werden: Sie definieren Eigenschaften des globalen Objekts. Im Gegensatz zu Eigenschaften, die durch ordnungsgemäße var-Deklarationen definiert sind, können solche Eigenschaften aber mit dem delete-Operator (siehe 4.13.4) gelöscht werden. |