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"
Для получения дополнительной информации см. Деструктуризация.
Спецификации
Совместимость с браузерами
| Десктоп | Мобильные | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 |
См. также
© 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