logo
Ещё

В чем разница между var и let

Почти во всех языках программирования объявление переменных – то, с чего вы начинаете изучение ЯП. JavaScript уже здесь может поставить в тупик начинающих разработчиков: у языка есть 2 способа объявления переменных, оператор var и оператор let. Ниже – вкратце о том, чем они отличаются и какой вам стоит использовать.

Особенности объявления переменных в JavaScript

В первых редакциях языка для объявления переменных использовался var, которому потом дали альтернативу в виде let, поэтому рассматривать объявление будем на примере var – так будет проще понять, что улучшено в let. Итак, объявление переменной выглядит так:

var a;

Да, как видите, в переменной ничего пока не хранится – мы просто объявили имя, которое теперь ассоциируется с каким-то участком оперативной памяти. Теперь мы можем «положить что-то» в эту переменную, первичное присвоение называется инициализацией:

a = 50;

Часто это делают вместе, что и называется объявлением переменной, хотя по факту является объявлением + инициализацией:

var a = 50;

А теперь – немного магии: когда вы пишете «var a;», ваша переменная на самом деле неявно инициализируется значением «undefined», и вы можете обратиться к этому значению (что является очень плохой практикой).

Второй момент объявления связан с областью видимости. Если вы хотите создать глобальную переменную – вы просто пишете ее вне скрипта, и она автоматически становится видна в любой строке файла, это работает одинаково для всех языков программирования. А вот чем объявление переменной через var в JS отличается от остальных ЯП – у него нет понятия видимости блоков, переменная может иметь либо глобальную видимость, либо видимость в пределах функции. Например, вот как это работает в Java:

for (int i = 0; i < 5; i++) {

// Объявление переменной внутри цикла

int insideLoop = i * 2;

System.out.println("insideLoop: " + insideLoop);

}

// System.out.println("insideLoop: " + insideLoop); // Ошибка: cannot find symbol

Здесь мы внутри цикла объявили переменную (на самом деле – 2 переменные, есть еще «i»), и она доступна только в цикле – если мы пытаемся обратиться к ней вне цикла, компилятор выдает ошибку. В JavaScript это работает иначе:

for (var j = 0; j < 3; j++) {

var greeting = 'Hi there!';

console.log(greeting); // 'Hi there!'

}

console.log(j); // 3

console.log(greeting); // 'Hi there!'

Как видите, мы спокойно получаем доступ к переменным, которые были объявлены внутри блока, что – контр-интуитивно и может приводить к неочевидным ошибкам, вроде «i» в цикле, начинающейся не с 0.

Обе особенности, которые мы описали выше, вызваны поднятием переменной (hoisting). Поднятие переменной – это когда переменная, объявленная в любом месте функции, перемещается вверх с присвоением значения undefined. Если мы пишем следующий код:

console.log(myVar); // undefined

var myVar = 5;

console.log(myVar); // 5

, то во время компиляции он превращается в такой:

var myVar = undefined;

console.log(myVar); // undefined

myVar = 5;

console.log(myVar); // 5

Поднятие переменной – спорный механизм, который не нашел большого применения, поэтому разработчики стандарта языка решили кардинально решить проблему – ввели новый оператор let, который работает более предсказуемо.

Разница между var и let

Let имеет именно такое поведение, которое разработчики ожидают от команды объявления переменной: с областью видимости в рамках блока. Пример:

if (true) {

let message = 'Hello, world!';

console.log(message); // 'Hello, world!'

}

console.log(message); // ReferenceError: message is not defined

Как видите, переменная «message», созданная в блоке «if», теперь доступна только в этом блоке.

С обращением к еще не инициализированной переменной все сложнее – стандарт языка все еще позволяет это, даже если вы используете let. Но многие компиляторы на такое действие выдают предупреждение, поэтому вам стоит привыкать к тому, что пользоваться неинициализированной переменной – нельзя.

Часто задаваемые вопросы

Так что лучше использовать – var или let?

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

Как работает const?

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

Кратко о главном

  • Var – способ объявления переменных, использовавшийся в первых стандартах языка, затем ему на смену пришел let.
  • Var позволяет создать переменные с глобальной областью видимости или областью видимости в рамках функции, let позволяет создавать переменные с областью видимости в рамках блока.
  • И var, и let позволяют обращаться к переменным до их инициализации, но в случае с let компилятор выдает предупреждение.