Alxblsk.com Logo
RE•DONE
Blog by Aliaksei Belski

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

Published: May 1st, 2017, Updated: September 12th, 2020variableshoistingjavascriptECMAScript2015

Объявляем перемен�ные, используя 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.