Блочная область видимости: let и const

let и const — объявления переменных с блочной областью видимости (block scope), введённые в ES6; в отличие от var, они ограничены парой фигурных скобок {} и не «всплывают» в используемом виде.

Зачем нужно

var создаёт переменные с функциональной областью видимости, что приводит к трудноуловимым ошибкам (утечка переменных из блоков, классическая проблема с циклами). let и const предсказуемы, читаемы и соответствуют ожиданиям большинства разработчиков.

Где используется

  • const — для любых значений, которые не переназначаются (объекты, функции, константы)
  • let — для переменных, которым нужно переназначение (счётчики, временные значения)
  • Любые блоки кода: циклы, условия, функции, модули

let

// Блочная область видимости
if (true) {
  let x = 10;
  console.log(x); // 10
}
// console.log(x); // ReferenceError: x is not defined

// В цикле — каждая итерация имеет свой x
for (let i = 0; i < 3; i++) {
  setTimeout( => console.log(i), 100);
}
// 0, 1, 2 — корректно!

// Нельзя объявить повторно в одной области
let a = 1;
// let a = 2; // SyntaxError

const

// Нельзя переназначить
const PI = 3.14159;
// PI = 3; // TypeError

// Но содержимое объекта/массива можно изменять
const user = { name: 'Иван' };
user.name = 'Мария'; // OK
user.age = 30;       // OK
// user = {};        // TypeError — переназначение запрещено

const arr = [1, 2, 3];
arr.push(4);    // OK
arr[0] = 10;    // OK
// arr = ;    // TypeError

Temporal Dead Zone (TDZ)

// let и const существуют в TDZ от начала блока до объявления
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;

// var — иначе:
console.log(b); // undefined (var всплывает с undefined)
var b = 5;

Сравнение var / let / const

var let const
Область видимости Функция / глобальная Блок Блок
Hoisting Да (undefined) TDZ TDZ
Переобъявление Да Нет Нет
Переназначение Да Да Нет

Практическое правило

// 1. По умолчанию — const
const config = { debug: false };
const greet = (name) => `Привет, ${name}`;

// 2. let — только если нужно переназначение
let count = 0;
count++;

// 3. var — не использовать в современном коде

Частые ошибки

  • const объект нельзя "заморозить" автоматическиconst obj защищает ссылку, не значение; для иммутабельности используйте Object.freeze(obj).
  • Объявление let в switch без блока — все case одной switch — один блок; для блочной области внутри case оборачивайте в {}.
  • Путать TDZ с undefined — обращение к let/const до объявления — это ReferenceError, а не undefined.

Связанные темы

Ресурсы


⚡ Источник: Why does everyone use var, let and const incorrectly · AsForJS

  • 📅 2021-04-11 · YouTube
  • Тезисы:
    • var НЕ устаревший — в спецификации ECMAScript нет пометки "deprecated". На javascript.info висит "the old var" — это домыслы, а не стандарт
    • let/const — это ссылки на области памяти, действующие в блочном scope с момента объявления
    • На каждое использование let/const Ignition (интерпретатор V8) генерирует команду ThrowReferenceErrorIfHole — проверку TDZ. У var этой команды НЕТ
    • Байткод var и let отличается ТОЛЬКО этой проверкой — больше ничем
    • Без понимания var нельзя писать высокопроизводительный код
  • Цитата: «Объявление этой переменной, как вам любят говорить, а на самом деле это не переменные, а ссылки на области памяти»

⚡ Источник: A fat point in the debate about var let and const · AsForJS

  • 📅 2025-01-29 · YouTube
  • Тезисы: финальный аргумент спора — выбор между var/let/const это вопрос производительности и понимания контекстов, а не "современности"