var

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

Оператор var объявляет переменную, инициализируя ее, при необходимости.

Синтаксис

var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];
varnameN
Имя переменной. Может использоваться любой допустимый идентификатор.
valueN
Значение переменной. Любое допустимое выражение.

Описание

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

Присвоение значения необъявленной переменной подразумевает, что она будет создана как глобальная переменная (переменная становится свойством глобального объекта) после выполнения присваивания значения. Различия между объявленной и необъявленной переменными следующие:

1. Объявленные переменные ограничены контекстом выполнения, в котором они были объявлены. Необъявленные переменные всегда глобальны.

function x() {
  y = 1; // возбудит ReferenceError в "строгом режиме"
  var z = 2;
}

x();

console.log(y); // выведет "1" 
console.log(z); // возбудит ReferenceError: z не определён вне x

2. Объявленные переменные инициализируются до выполнения любого кода. Необъявленные переменные не существуют до тех пор, пока к ним не выполнено присваивание.

console.log(a);    // Возбудит ReferenceError.
console.log('still going...'); // Не выполнится.
var a;
console.log(a);                // Выведет "undefined" или "", в зависимости от браузера.
console.log('still going...'); // Выведет "still going...".

3. Объявленные переменные, независимо от контекста выполнения, являются ненастраиваемыми свойствами. Необъявленные переменные это настраиваемые свойства (т.е. их можно удалять).

var a = 1;
b = 2;

delete this.a; // Возбудит TypeError в "строгом режиме". В "нестрогом режиме" будет ошибка без уведомления.
delete this.b;

console.log(a, b); // Возбудит ReferenceError. 
// Свойство 'b' было удалено и больше не существует.

Из-за перечисленных различий, использование необъявленных переменных может привести к непредсказуемым последствиям. Рекомендовано всегда объявлять переменные, вне зависимости, находятся они внутри функции или в глобальном контексте. Присваивание значения необъявленной переменной в строгом режиме ECMAScript 5 возбуждает ошибку.

Поднятие переменных

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

bla = 2
var bla;
// ...

// читается как:

var bla;
bla = 2;

Поэтому объявление переменных рекомендовано выносить в начало их области видимости (в начало глобального кода или в начало функции). Это даёт понять какие переменные принадлежат функции (т.е. являются локальными), а какие взяты из so it's clear which variables are function scoped (local) and which are resolved on the scope chain.

Примеры

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

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); // undefinedA

В примере, x и y объявлены до выполнение кода, присвоение выполняется позже. Когда происходит присваивание "x = y", y уже существует со значением 'undefined', так что ошибка ReferenceError не возбуждается. И переменной x присваивается неопределённое значение. Потом переменной y присваивается значение 'A'. Получается, что после выполнения первой строки кода x === undefined && y === 'A', отсюда и результат.

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

var x = 0;

function f(){
  var x = y = 1; // x - объявляется локально. y - глобально!
}
f();

console.log(x, y); // 0, 1
// значение x взято из глобальной переменной, как и ожидалось
// значение переменной y доступно глобально

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

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

var x = 0;  // x объявлена глобально, затем присваивается значение 0

console.log(typeof z); // undefined, пока еще z не существет

function a() { // когда функция a вызванна,
  var y = 2;   // y объявляется локально в функции a, затем присваивается 2

  console.log(x, y);   // 0 2 

  function b() {       // когда функция b вызванна
    x = 3;  // присваивается 3 существующей глобальной x
    y = 4;  // присваивается 4 существующей внешней y
    z = 5;  // создается новая глобальная переменная z и присваивается значение 5. 
  }         // (Порождает ReferenceError в strict mode(строгом режиме).)

  b();     // вызов b создает z как глобальную переменную
  console.log(x, y, z);  // 3 4 5
}

a();                   // вызов a также вызывает b
console.log(x, z);     // 3 5
console.log(typeof y); // undefined, так как y это локальная переменная для функции a

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

Спецификация Статус Комментарий
ECMAScript 1st Edition (ECMA-262) Стандарт Начальное определение. Имплементировано в JavaScript 1.0
ECMAScript 5.1 (ECMA-262)
Определение 'var statement' в этой спецификации.
Стандарт  
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'variable statement' в этой спецификации.
Стандарт  
ECMAScript 2017 Draft (ECMA-262)
Определение 'variable statement' в этой спецификации.
Черновик  

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

Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базовая поддержка (Да) (Да) (Да) (Да) (Да)
Возможность
Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базовая поддержка (Да) (Да) (Да) (Да) (Да) (Да)

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: AlexKhram, shalimski, Saviloff
 Обновлялась последний раз: AlexKhram,