Блочная область видимости: 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.
Связанные темы
- _MOC JavaScript
- _MOC Функции
- Глобальная и локальная область видимости
- Замыкания (Closures)
- Замыкание в цикле -- распространённая ошибка
Ресурсы
⚡ Источник: 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/constIgnition (интерпретатор 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это вопрос производительности и понимания контекстов, а не "современности"