Start · Sprachen · JavaScript · Referenz · var

var

Anweisung

Die <code>var</code>-Anweisung deklariert function-scoped oder global-scoped Variablen und initialisiert sie optional mit einem Wert.

seit JavaScript ES1 Kategorie: syntax

Signatur

var name1; var name1 = value1; var name1 = value1, name2 = value2; var name1, name2 = value2; var name1 = value1, name2, /* …, */ nameN = valueN;

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

Typ
void
Beschreibung
Eine 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.

Siehe auch