Signatur
Beschreibung
Die var-Anweisung deklariert function-scoped oder global-scoped Variablen und initialisiert sie optional mit einem Wert.
Der Scope einer mit var deklarierten Variablen ist eine der folgenden von geschweiften Klammern umschlossenen Syntaxen, die die var-Anweisung am engsten umgibt:
- Funktionsrumpf
- Static initialization block
Oder wenn keine der obigen zutrifft:
- Das aktuelle Modul, für Code, der im Modul-Modus läuft
- Der globale Scope, für Code, der im Skript-Modus läuft.
Wichtig: Andere Block-Konstrukte, einschließlich block statements, try...catch, switch, Headern von for-Anweisungen, erzeugen keinen Scope für var, und mit var innerhalb eines solchen Blocks deklarierte Variablen können auch außerhalb des Blocks weiter referenziert werden.
In einem Skript wird eine mit var deklarierte Variable als non-configurable Eigenschaft des globalen Objekts hinzugefügt. Das bedeutet, ihr Property Descriptor kann nicht geändert werden und sie kann nicht mit delete gelöscht werden. JavaScript verfügt über automatische Speicherverwaltung, und es wäre nicht sinnvoll, den delete-Operator auf einer globalen Variablen verwenden zu können.
Sowohl in Node.js CommonJS-Modulen als auch in nativen ECMAScript-Modulen sind Top-Level-Variablendeklarationen auf das Modul beschränkt und werden nicht als Eigenschaften zum globalen Objekt hinzugefügt.
Die Liste, die dem var-Schlüsselwort folgt, wird binding list genannt und ist durch Kommata getrennt, wobei die Kommata keine Comma-Operatoren und die =-Zeichen keine Zuweisungsoperatoren sind. Initialisierer späterer Variablen können auf frühere Variablen in der Liste verweisen und deren initialisierten Wert erhalten.
Hoisting
var-Deklarationen werden, egal wo sie im Skript vorkommen, verarbeitet, bevor irgendein Code im Skript ausgeführt wird. Eine Variable irgendwo im Code zu deklarieren ist äquivalent dazu, sie oben zu deklarieren. Das bedeutet auch, dass eine Variable scheinbar verwendet werden kann, bevor sie deklariert ist. Dieses Verhalten wird Hoisting genannt, da es so aussieht, als würde die Variablendeklaration an den Anfang der Funktion, des static initialization block oder des Skriptquelltextes verschoben, in dem sie vorkommt.
Nur die Deklaration einer Variablen wird gehoistet, nicht ihre Initialisierung. Die Initialisierung erfolgt erst, wenn die Zuweisungsanweisung erreicht wird. Bis dahin bleibt die Variable undefined (aber deklariert).
Redeklarationen
Doppelte Variablendeklarationen mit var lösen keinen Fehler aus, auch nicht im strict mode, und die Variable verliert ihren Wert nicht, es sei denn, die Deklaration hat einen Initialisierer.
var-Deklarationen können auch im gleichen Scope wie eine function-Deklaration stehen. Sowohl die Funktionsdeklaration als auch die var-Deklaration werden an den Anfang gehoistet, so dass der Funktionswert nur vom Beginn seines Scopes bis zum Initialisierer oder der ersten Zuweisung der Variablen zugänglich ist, unabhängig von der relativen Position der beiden Deklarationen im Quellcode.
var-Deklarationen können nicht im gleichen Scope wie eine let-, const-, class- oder import-Deklaration stehen.
Eine var-Deklaration innerhalb eines Funktionsrumpfs kann denselben Namen wie ein Parameter haben.
Eine var-Deklaration innerhalb eines catch-Blocks kann denselben Namen wie der an catch gebundene Identifier haben, aber nur wenn das catch-Binding ein einfacher Identifier und kein Destructuring-Pattern ist. Dies ist eine deprecated Syntax und du solltest dich nicht darauf verlassen. In diesem Fall wird die Deklaration nach außerhalb des catch-Blocks gehoistet, aber jeder Wert, der innerhalb des catch-Blocks zugewiesen wird, ist außerhalb nicht sichtbar.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $nameN Pflicht | identifier | — | Der Name der zu deklarierenden Variablen. Jeder muss ein gültiger JavaScript-Identifier oder ein Destructuring Binding Pattern sein. |
| $valueN | any | undefined | Initialer Wert der Variablen. Kann ein beliebiger gültiger Ausdruck sein. Standardwert ist undefined. |
Rückgabewert
var-Anweisung gibt keinen Wert zurück.Beispiele
Function scope
function foo() {
var x = 1;
function bar() {
var y = 2;
console.log(x); // 1 (function `bar` closes over `x`)
console.log(y); // 2 (`y` is in scope)
}
bar();
console.log(x); // 1 (`x` is in scope)
console.log(y); // ReferenceError, `y` is scoped to `bar`
}
foo();
Kein Block-Scope
for (var a of [1, 2, 3]);
console.log(a); // 3
Nicht löschbar auf dem globalen Objekt
"use strict";
var x = 1;
Object.hasOwn(globalThis, "x"); // true
delete globalThis.x; // TypeError in strict mode. Fails silently otherwise.
delete x; // SyntaxError in strict mode. Fails silently otherwise.
Hoisting
bla = 2;
var bla;
Nur die Deklaration wird gehoistet
function doSomething() {
console.log(bar); // undefined
var bar = 111;
console.log(bar); // 111
}
Redeklaration
var a = 1;
var a = 2;
console.log(a); // 2
var a;
console.log(a); // 2; not undefined
var und function-Deklaration
console.log(typeof a); // "function"
function a() {}
var a;
console.log(typeof a); // "function"
var mit initialisierter Funktion
var a = 1;
function a() {}
console.log(a); // 1
Konflikt mit let
var a = 1;
let a = 2; // SyntaxError: Identifier 'a' has already been declared
var in Block, let außerhalb
let a = 1;
{
var a = 1; // SyntaxError: Identifier 'a' has already been declared
}
let in Child-Scope
var a = 1;
{
let a = 2;
}
var mit gleichem Namen wie Parameter
function foo(a) {
var a = 1;
console.log(a);
}
foo(2); // Logs 1
var im catch-Block
try {
throw new Error();
} catch (e) {
var e = 2; // Works
}
console.log(e); // undefined
Zwei Variablen deklarieren und initialisieren
var a = 0,
b = 0;
Zwei Variablen mit einem einzigen String-Wert zuweisen
var a = "A";
var b = a;
Äquivalente Kurzform
var a, b = a = "A";
Reihenfolge beachten
var x = y,
y = "A";
console.log(x, y); // undefined A
Initialisierung mehrerer Variablen (non-strict)
var x = 0;
function f() {
var x = y = 1; // Declares x locally; declares y globally.
}
f();
console.log(x, y); // 0 1
// In non-strict mode:
// x is the global one as expected;
// y is leaked outside of the function, though!
Gleiches Beispiel im strict mode
"use strict";
var x = 0;
function f() {
var x = y = 1; // ReferenceError: y is not defined
}
f();
console.log(x, y);
Implizite Globale und äußerer Funktions-Scope
var x = 0; // Declares x within file scope, then assigns it a value of 0.
console.log(typeof z); // "undefined", since z doesn't exist yet
function a() {
var y = 2; // Declares y within scope of function a, then assigns it a value of 2.
console.log(x, y); // 0 2
function b() {
x = 3; // Assigns 3 to existing file scoped x.
y = 4; // Assigns 4 to existing outer y.
z = 5; // Creates a new global variable z, and assigns it a value of 5.
// (Throws a ReferenceError in strict mode.)
}
b(); // Creates z as a global variable.
console.log(x, y, z); // 3 4 5
}
a(); // Also calls b.
console.log(x, z); // 3 5
console.log(typeof y); // "undefined", as y is local to function a
Deklaration mit Destructuring
const result = /(a+)(b+)(c+)/.exec("aaabcc");
var [, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"
// Wichtig · Fallstricke
Hinweis: var-Deklarationen werden nur an den Anfang des aktuellen Skripts gehoistet. Wenn du zwei <script>-Elemente in einem HTML hast, kann das erste Skript nicht auf Variablen zugreifen, die vom zweiten deklariert werden, bevor das zweite Skript verarbeitet und ausgeführt wurde.