var, let, const, hoisting, TDZ
↑ 1.4 JavaScript: основы · ← Предыдущая · → Следующая
Зачем это на собесе
Вопросы про «всплытие» и временную мёртвую зону — обязательная часть собеседования по JS.
Объяснение
var | let | const | |
|---|---|---|---|
| Область | функция | блок | блок |
| Hoisting | поднимается, инициализируется undefined | поднимается, но недоступна до объявления (TDZ) | как let |
| Повторное объявление | разрешено | нет | нет |
| Переприсваивание | да | да | нет (но объект внутри изменяем) |
Свойство window | да (глобально) | нет | нет |
Hoisting — объявления обрабатываются при создании контекста выполнения до выполнения кода.
console.log(a); // undefined (var поднята)
var a = 1;
console.log(b); // ReferenceError: Cannot access 'b' before initialization (TDZ)
let b = 2;
hello(); // работает: Function Declaration поднимается целиком
function hello() { console.log("hi"); }
bye(); // TypeError: bye is not a function (var поднята как undefined)
var bye = function () {};
for (var i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 3 3 3
for (let j = 0; j < 3; j++) setTimeout(() => console.log(j)); // 0 1 2 (новая привязка на итерацию)
const user = { name: "A" };
user.name = "B"; // ок: изменяется содержимое
// user = {}; // TypeError
Object.freeze(user); // мелкая неизменяемостьTDZ (Temporal Dead Zone) — период от начала блока до строки объявления let/const/class, когда обращение к переменной вызывает ReferenceError.
Нюансы и подводные камни
- Используйте
constпо умолчанию,letпри переприсваивании,varне используйте. constне делает объект неизменяемым: нуженObject.freeze(мелко) или иммутабельные подходы.typeofв TDZ тоже бросает исключение.- Function Declaration в блоках имеет особенности в нестрогом режиме.
- Глобальные
varсоздают свойстваwindowи могут конфликтовать со сторонним кодом.
Практика
- Предскажите вывод 6 фрагментов с
var/letиsetTimeoutв цикле. - Найдите в коде
varи замените. - Объясните, почему
letв цикле работает иначе.
Вопросы с ответами
Что такое hoisting?
Подъём объявлений в начало области видимости при создании контекста выполнения.
Что такое TDZ?
Промежуток до инициализации
let/const, в котором обращение вызывает ReferenceError.
Почему
constобъект можно менять?
constзапрещает переприсваивание привязки, но не изменение содержимого объекта.