Spec-Zone.ru › JavaScript

var

Baseline Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с июля 2015 года.

Оператор var объявляет переменные, имеющие область видимости функции или глобальную область видимости, опционально инициализируя каждую значением.

Попробуйте

var x = 1;

if (x === 1) {
  var x = 2;

  console.log(x);
  // Expected output: 2
}

console.log(x);
// Expected output: 2

Синтаксис

var name1;
var name1 = value1;
var name1 = value1, name2 = value2;
var name1, name2 = value2;
var name1 = value1, name2, /* …, */ nameN = valueN;
nameN
Имя переменной для объявления. Каждое имя должно быть допустимым идентификатором JavaScript или шаблоном деструктурирующего связывания.
valueN Необязательно
Начальное значение переменной. Это может быть любое допустимое выражение. Значение по умолчанию — undefined.

Описание

Областью видимости переменной, объявленной с помощью var, является один из следующих синтаксисов, заключенных в фигурные скобки, который наиболее близко содержит оператор var:

  • Тело функции
  • Статический блок инициализации

Или, если ни одно из вышеперечисленных не применимо:

  • Текущий модуль, для кода, выполняемого в режиме модуля
  • Глобальная область видимости, для кода, выполняемого в режиме скрипта.
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();

Важно отметить, что другие блочные конструкции, включая блочные операторы, try...catch, switch, заголовки одного из операторов for, не создают областей видимости для var, и переменные, объявленные с помощью var внутри такого блока, могут по-прежнему использоваться вне блока.

for (var a of [1, 2, 3]);
console.log(a); // 3

В скрипте переменная, объявленная с помощью var, добавляется как неконфигурируемое свойство глобального объекта. Это означает, что ее дескриптор свойства нельзя изменить, и ее нельзя удалить с помощью delete. JavaScript имеет автоматическое управление памятью, и не имеет смысла использовать оператор delete для глобальной переменной.

"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.

Как в модулях Node.js CommonJS, так и в нативных модулях ECMAScript, объявления переменных верхнего уровня имеют область видимости модуля и не добавляются как свойства к глобальному объекту.

Список, следующий за ключевым словом var, называется списком связывания и разделен запятыми, причем запятые не являются операторами запятой, а знаки = не являются операторами присваивания. Инициализаторы последующих переменных могут ссылаться на предыдущие переменные в списке и получать инициализированное значение.

Поднятие (Hoisting)

Объявления var, где бы они ни находились в скрипте, обрабатываются до выполнения любого кода в этом скрипте. Объявление переменной в любом месте кода эквивалентно объявлению ее в начале. Это также означает, что переменная может использоваться до ее объявления. Такое поведение называется поднятием (hoisting), поскольку кажется, что объявление переменной перемещается в начало функции, статического блока инициализации или исходного кода скрипта, в котором оно встречается.

Примечание: Объявления var поднимаются только в начало текущего скрипта. Если у вас есть два элемента <script> в одном HTML, первый скрипт не сможет получить доступ к переменным, объявленным вторым, до того, как второй скрипт будет обработан и выполнен.

bla = 2;
var bla;

Это неявно подразумевается как:

var bla;
bla = 2;

По этой причине рекомендуется всегда объявлять переменные в начале их области видимости (в начале глобального кода и в начале кода функции), чтобы было ясно, какие переменные относятся к текущей функции.

Поднимается только объявление переменной, но не ее инициализация. Инициализация происходит только тогда, когда достигается оператор присваивания. До этого момента переменная остается undefined (но объявленной):

function doSomething() {
  console.log(bar); // undefined
  var bar = 111;
  console.log(bar); // 111
}

Это неявно подразумевается как:

function doSomething() {
  var bar;
  console.log(bar); // undefined
  bar = 111;
  console.log(bar); // 111
}

Повторные объявления

Повторные объявления переменных с использованием var не вызовут ошибку, даже в строгом режиме, и переменная не потеряет свое значение, если только объявление не содержит инициализатор.

var a = 1;
var a = 2;
console.log(a); // 2
var a;
console.log(a); // 2; not undefined

Объявления var также могут находиться в той же области видимости, что и объявление function. Как объявление функции, так и объявление var поднимаются вверх, поэтому значение функции доступно только с начала ее области видимости до инициализатора переменной или первого присваивания, независимо от относительного положения двух объявлений в исходном коде.

console.log(typeof a); // "function"
function a() {}
var a;
console.log(typeof a); // "function"
var a = 1;
function a() {}
console.log(a); // 1

Объявления var не могут находиться в той же области видимости, что и объявление let, const, class или import.

var a = 1;
let a = 2; // SyntaxError: Identifier 'a' has already been declared

Поскольку объявления var не имеют области видимости блоков, это также относится к следующему случаю:

let a = 1;
{
  var a = 1; // SyntaxError: Identifier 'a' has already been declared
}

Это не относится к следующему случаю, где let находится в дочерней области видимости var, а не в той же области видимости:

var a = 1;
{
  let a = 2;
}

Объявление var внутри тела функции может иметь то же имя, что и параметр.

function foo(a) {
  var a = 1;
  console.log(a);
}

foo(2); // Logs 1

Объявление var внутри блока catch может иметь то же имя, что и идентификатор, связанный с catch, но только если связывание catch является простым идентификатором, а не шаблоном деструктуризации. Это устаревший синтаксис, и на него не следует полагаться. В этом случае объявление поднимается за пределы блока catch, но любое значение, присвоенное внутри блока catch, невидимо снаружи.

try {
  throw new Error();
} catch (e) {
  var e = 2; // Works
}
console.log(e); // undefined

Примеры

Объявление и инициализация двух переменных

var a = 0,
  b = 0;

Присваивание двух переменных с одним строковым значением

var a = "A";
var b = a;

Это эквивалентно:

var a, b = a = "A";

Обратите внимание на порядок:

var x = y,
  y = "A";
console.log(x, y); // undefined A

Здесь x и y объявлены до выполнения какого-либо кода, но присваивания происходят позже. В момент оценки x = y y существует, поэтому ReferenceError не выбрасывается, и его значение равно undefined. Следовательно, x присваивается неопределенное значение. Затем y присваивается значение "A".

Инициализация нескольких переменных

Будьте внимательны к синтаксису var x = y = 1 — y фактически не объявляется как переменная, поэтому y = 1 является неквалифицированным присваиванием идентификатора, которое создает глобальную переменную в нестрогом режиме.

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!

Тот же пример, что и выше, но в строгом режиме:

"use strict";

var x = 0;
function f() {
  var x = y = 1; // ReferenceError: y is not defined
}
f();

console.log(x, y);

Неявные глобальные переменные и область видимости внешней функции

Переменные, которые кажутся неявными глобальными, могут быть ссылками на переменные во внешней области видимости функции:

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

Объявление с деструктуризацией

Левая часть каждого = также может быть шаблоном связывания. Это позволяет создавать несколько переменных одновременно.

const result = /(a+)(b+)(c+)/.exec("aaabcc");
var [, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"

Для получения дополнительной информации см. Деструктуризация.

Спецификации

Спецификация
Спецификация языка ECMAScript® 2027
# sec-variable-statement

Совместимость с браузерами

Десктоп Мобильные Сервер
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
var
1
12
1
3
1
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0

См. также

  • let
  • const

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API