Область видимости - это пространство, в котором значение переменной определяется и доступно.

В JavaScript есть 3 типа областей видимости:

  • Глобальный масштаб
  • Объем функции
  • Область действия блока

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

Переменные, определенные с помощью ключевого слова let или const, имеют область действия блока.

Для более подробного объяснения области видимости см. Мой другой пост под названием Область действия в JavaScript.

Подъем

Когда программа JavaScript запускается, она сначала анализирует сценарий и ищет объявления переменных или функций. Если он обнаруживает какие-либо объявления переменных или функций, он «поднимает» их на вершину соответствующих областей и обрабатывает их, прежде чем приступить к оценке остальной части кода JavaScript. Этот процесс называется «Подъем».

Подъем влияет на объявление переменной, но НЕ на ИНИЦИАЛИЗАЦИЮ / НАЗНАЧЕНИЕ значения.

Примеры подъема на JS:

Помните, что подъем применяется только к объявлениям переменных, а не к инициализации переменных. В приведенном ниже примере будет возвращено значение «undefined», поскольку x инициализирован и определен во второй строке и, следовательно, не поднимается над вызовом console.log().

В приведенном ниже коде будет напечатано 2. Поскольку переменная y объявлена ​​в строке 3, но не инициализирована, она будет поднята в начало программы над инициализацией y = 2. Таким образом, к моменту фактического вызова console.log(y) для y будет определено значение 2.

y = 2;
console.log(y); // Returns 2
var y;

// Same As
var y;
y = 2;
console.log(y);

ПРИМЕЧАНИЕ. Хотя подъем применяется к переменным, объявленным с помощью var, let или const, подъем действительно помогает только переменным, объявленным с помощью var. Переменные, объявленные с ключевым словом let, возвращают ReferenceError, если они не инициализированы (подробности см. В разделе TDZ ниже). Вы также не можете объявить переменную с ключевым словом const, не инициализировав сразу ее значение. Если вы попытаетесь это сделать, вы получите сообщение «SyntaxError: Missing initializer in const Declaration».

Различия между var, let и const

вар

Переменная, которая объявлена ​​(но не инициализирована) с использованием ключевого слова var, возвращает значение undefined, если к ней обращаются до ее инициализации (см. Раздел о подъеме).

console.log(x); // Returns undefined
var x = 1; // variable declaration and initialization
console.log(x); // Returns 1

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

Переменные, объявленные с помощью var, могут быть повторно объявлены.

var x = 1;
console.log(x); // 1

var x = 2;
console.log(x); // 2

позволять

Переменные, объявленные с помощью let, имеют блочную область видимости. Мы можем объявлять переменные с одинаковыми именами только в том случае, если они находятся в разных блоках, используя let.

В отличие от var, переменные, объявленные с помощью ключевого слова let, не могут быть повторно объявлены в той же области

let x = 1;
let x = 2; // Uncaught SyntaxError: Identifier 'x' has already been declared

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

let x = 1;
console.log(x); // 1

x = 2; // This is ok because you are not trying to redeclare x, just redefine its value
console.log(x); // 2

Временная мертвая зона

Временная мертвая зона (TDZ) - это область в текущей области между ее началом и окончательной инициализацией переменной. TDZ применяется к переменным, объявленным с ключевым словом let. Переменная, объявленная с let, недоступна (возвратит 'ReferenceError') в TDZ.

const

Подобно переменным, объявленным с помощью let, переменные, объявленные с помощью ключевого слова const, имеют блочную область видимости.

Также как и let, переменные, объявленные с помощью const, не могут быть повторно объявлены.

Однако, в отличие от переменных, объявленных с let, переменные, объявленные с const ДОЛЖНЫ быть инициализированы сразу. В противном случае вы получите ошибку «SyntaxError: Отсутствует инициализатор в объявлении константы».

Самое главное, переменные, объявленные и инициализированные с помощью ключевого слова const, нельзя изменить путем переназначения (см. Примечание ниже). Это связано с тем, что ключевое слово const делает имя переменной доступным только для чтения, предотвращая доступ на запись к значению, хранящемуся в памяти, через назначенную переменную. Если задуматься, становится понятно, почему это так. Если вы хотите создать переменную, которую нельзя легко изменить, вам нужно знать ее значение, иначе вы просто получите постоянную переменную со значением «undefined».

ПРИМЕЧАНИЕ. Обратите внимание, что переменные, инициализированные с помощью ключевого слова const, нельзя изменить путем переназначения. Это не означает, что значение постоянного значения не может измениться, это означает только то, что вы не можете изменить его, используя имя переменной напрямую. Хотя нет другого способа изменить строковую или числовую переменную, кроме, например, переназначения, вы можете изменить свойства объекта.

Какое объявление переменной лучше всего и что мне следует использовать?

Я прочитал статью Веса Боса и мне нравится его совет:

  1. Используйте ключевое слово const для объявления переменных по умолчанию, если вы не знаете, что вашей переменной нужно будет изменить свое значение (в этом случае используйте let).
  2. Используйте ключевое слово let для объявления переменной, если вы знаете, что ее значение изменится (например, итератор).
  3. За исключением особых случаев, избегайте использования ключевого слова var для объявления переменных.

Резюме: разница между переменными, объявленными с помощью ключевых слов «var», «let» и «const»:

var

  • Область действия: глобальная или функция
  • Может быть переобъявлен? да
  • Возможность повторной инициализации? да

let

  • Объем: глобальный или блок
  • Может быть переобъявлен? Нет
  • Возможность повторной инициализации? да

const

  • Объем: глобальный или блок
  • Может быть переобъявлен? Нет
  • Возможность повторной инициализации? Нет

Ресурсы