Объявляем переменные, используя var, let и const

EcmaScript 2015 (также известный как ES6), привнес новые способы объявления переменных в Javascript: let и const. Однако, возможность объявить var никуда не делась. Давайте разберемся, что меняется с приходом новых ключевых слов.
Старый, добрый var
Филососия Javascript в контексте объявления переменных с момента появления var следующая:
- Значение при инициализации не требуется;
В случае отсутствия присваемого значения, в переменной будет храниться значение
undefined.
var greeting = 'Добро пожаловать';
var goodbye; // undefined- Область видимости ограничена функцией; В отличие от других популярных языков программирования, использование фигурных скобок (блоков) не приводит к созданию новой области видимости. Поэтому данные в переменных могут быть переписаны (например, внутри условного оператора).
function combineMessage(name) {
var message = 'Добро пожаловать';
if (name) {
var message = message + ', ' + name;
}
return message; // Добро пожаловать, Коля
}- Все объявленные внутри одной области видимости переменные "всплывают" до начала исполнения кода.
Всплытие ("hoisting") означает, что вне зависимости от того, в каком месте области видимости будет описана переменная, она будет объявлена и проинициализирована значением
undefined.
function greeting() {
console.log(message); // undefined
var message = 'Добро пожаловать';
}Времена меняются
Однако, если вы планируете писать на ES2015, старых знаний будет недостаточно.
В большинстве случаев, мы объявляем переменную для хранения едиственного неизменного значения. Для того, чтобы избежать ошибок с неявным изменением таких значений, было введено ключевое слово const, которое позволяет выполнить лишь одно присваивание в рамках области видимости. Есть лишь одна оговорка: const не обеспечивает неизменности полей/значений сложных типов данных (иммутабельности). Это значит, что в массив, к примеру, можно добавить новое значение, но перезаписать сам массив не удастся.
function getHolidays() {
const holidays = [1, 2, 8, 9];
holidays.push(15); // Добавит новое значение в конец массива
holidays = []; //TypeError, новое присваивание к константе невозможно
const holidays = []; // SyntaxError, константа уже определена
}В остальных ситуациях, когда значение может быть изменено по ходу работы программы, в ES2015 предусмотрено использование ключевого слова let. В некотором смысле, это замена для var, с некоторыми особенностями:
- Переменная может быть определена на уровне блока
function loop() {
let index = -1;
for (let index = 0; index < 5; index++) {
console.log(index); // Поочередно 0, 1, 2, 3, 4
}
console.log(index); //-1
}- Переменная не "всплывает" до начала исполнения функции
function checkBalance() {
console.log(balance); // ReferenceError, переменная не определена
let balance = 100;
}Итог
- В большинстве случаев,
const- идеальный вариант, особенно для примитивов. В случае со сложными типами данных, вам все равно придется следить за "внутренностями", но как минимум, вы будете уверены, что ссылка объект не будет подменена. - При необходимости изменить значение переменной, используйте
let. Он избавился от болезни прародителя (всплытие) и работает внутри блоков. - Сейчас сложно представить сценарий использования
var. Разве что, возможно, при работе с try/catch.