Название | JavaScript – Das Handbuch für die Praxis |
---|---|
Автор произведения | David Flanagan |
Жанр | Математика |
Серия | |
Издательство | Математика |
Год выпуска | 0 |
isbn | 9783960104926 |
Wiederholte Deklarationen
Es ist ein Syntaxfehler, den gleichen Namen mit mehr als einer let- oder const-Deklaration im selben Geltungsbereich zu verwenden. Dagegen ist es erlaubt – auch wenn man es tunlichst vermeiden sollte –, eine neue Variable mit dem gleichen Namen in einem verschachtelten Bereich (hier im Inneren des if-Blocks) zu deklarieren:
const x = 1; // x als globale Konstante deklarieren.
if (x === 1) {
let x = 2; // Innerhalb eines Blocks kann x sich auf einen anderen
// Wert beziehen.
console.log(x); // Gibt "2" aus.
}
console.log(x); // Gibt "1" aus: Wir befinden uns wieder im globalen
// Geltungsbereich.
let x = 3; // FEHLER! Syntaxfehler beim Versuch, x erneut zu deklarieren.
Deklarationen und Typen
Wenn Sie an statisch typisierte Sprachen wie C oder Java gewöhnt sind, erwarten Sie vielleicht, dass der Hauptzweck von Variablendeklarationen darin besteht, den Datentyp der Werte festzulegen, die einer Variablen zugewiesen werden können. Wie Sie gesehen haben, wird bei Variablendeklarationen2 kein Typ angegeben. Eine JavaScript-Variable kann einen Wert eines beliebigen Typs enthalten. Beispielsweise ist es in JavaScript erlaubt (an sich aber schlechter Programmierstil), einer Variablen erst eine Zahl und später dann einen String zuzuweisen:
let i = 10;
i = "ten";
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. |
3.10.3Destrukturierende Zuweisung
In ES6 wurde eine Art zusammengesetzte Deklarations- und Zuweisungssyntax eingeführt, die als destrukturierende Zuweisung bezeichnet wird. Bei einer solchen destrukturierenden Zuweisung steht als Wert auf der rechten Seite des Gleichheitszeichens ein Array oder ein Objekt (ein »strukturierter« Wert), während auf der linken Seite einer oder mehrere Variablennamen in einer Syntax angegeben werden, die der von Array- und Objektliteralen ähnelt. Wenn eine destrukturierende Zuweisung erfolgt, wird einer oder werden mehrere Werte aus dem rechtsseitig angegebenen Wert extrahiert (»destrukturiert«) und in den links genannten Variablen gespeichert. Eine destrukturierende Zuweisung wird vermutlich am häufigsten verwendet, um Variablen als Teil einer const-, let- oder var-Deklarationsanweisung zu initialisieren, aber sie kann auch in regulären Zuweisungsausdrücken (mit bereits deklarierten Variablen) vorgenommen werden. Und wie wir in 8.3.5 sehen werden, kann man die Destrukturierung ebenfalls bei der Definition der Parameter einer Funktion einsetzen.
Hier