← Назад к вопросам
Как работает Hoisting относительно var?
1.0 Junior🔥 281 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Hoisting и переменные var
Hoisting — один из самых неинтуитивных механизмов JavaScript. Это поведение, при котором объявления переменных и функций как будто бы "поднимаются" в начало области видимости (scope) перед выполнением кода.
Как работает Hoisting с var
Когда интерпретатор JavaScript обрабатывает код, он проходит в две фазы:
Фаза 1: Создание контекста выполнения (Creation Phase)
- Все объявления
varи функции скannируются - Переменные
varинициализируются со значениемundefined - Функции полностью поднимаются (и объявление, и тело)
Фаза 2: Выполнение (Execution Phase)
- Код выполняется строка за строй
- При встрече с назначением переменная получает реальное значение
Примеры Hoisting с var
Пример 1: Базовый hoisting
console.log(x); // undefined (не ошибка!)
var x = 5;
console.log(x); // 5
// Это воспринимается интерпретатором как:
var x; // объявление поднимается
console.log(x); // undefined
x = 5; // присваивание остаётся на месте
console.log(x); // 5
Пример 2: Hoisting функций
console.log(sayHi()); // "Привет!" — функция работает!
function sayHi() {
return "Привет!";
}
// Функция полностью поднимается:
function sayHi() {
return "Привет!";
}
console.log(sayHi()); // "Привет!"
Пример 3: Переменная vs функция
console.log(typeof name); // undefined (переменная)
console.log(typeof func); // function (функция)
var name = "Алиса";
function func() {}
// Интерпретатор видит это как:
var name; // поднялась, значение undefined
function func() {} // функция полностью поднялась
console.log(typeof name); // undefined
console.log(typeof func); // function
Пример 4: Hoisting в функциях
function example() {
console.log(y); // undefined
if (true) {
var y = 10;
}
console.log(y); // 10 — y видна за пределами блока if!
}
// Это работает, потому что var имеет function scope, а не block scope:
function example() {
var y; // поднялась в начало функции
console.log(y); // undefined
if (true) {
y = 10;
}
console.log(y); // 10
}
Отличие var от let и const
с let и const — Temporal Dead Zone (TDZ)
console.log(x); // ReferenceError: Cannot access x before initialization
let x = 5;
// let и const тоже поднимаются, но в Temporal Dead Zone
// Они недоступны от начала блока до строки объявления
Визуально:
// var — поднимается И инициализируется
var a;
console.log(a); // undefined ✓
a = 5;
// let/const — поднимаются, но НЕ инициализируются (TDZ)
// console.log(b); // ❌ ReferenceError
let b = 5;
console.log(b); // 5 ✓
Практические проблемы Hoisting
Проблема 1: Случайное переиспользование переменной
function process(items) {
var result = [];
for (var i = 0; i < items.length; i++) {
// вложенный цикл
for (var i = 0; i < 10; i++) { // ⚠️ ТА ЖЕ ПЕРЕМЕННАЯ i!
result.push(items[i]);
}
}
return result; // внешний i перезаписан
}
// Решение — использовать let
function process(items) {
const result = [];
for (let i = 0; i < items.length; i++) {
for (let i = 0; i < 10; i++) { // разные i
result.push(items[i]);
}
}
return result; // работает правильно
}
Проблема 2: Confusion с function scope
if (true) {
var x = 5;
}
console.log(x); // 5 — не undefined!
// let/const решают это:
if (true) {
let y = 5;
}
console.log(y); // ReferenceError — y не видна снаружи
Почему это важно знать
- Отладка: Понимание hoisting помогает объяснить странные ошибки
- Миграция кода: При переходе с var на let/const поведение меняется
- Code review: Нужно замечать потенциальные конфликты
- Интервью: Это classic question для проверки понимания JavaScript
Резюме
varобъявления поднимаются и инициализируютсяundefined- Присваивания остаются на месте
varимеет function scope (не block scope)letиconstподнимаются но не инициализируются (Temporal Dead Zone)- В современном коде используй
letиconst, избегайvar