> Что такое всплытие (hoisting) в JavaScript? (JavaScript)

Уровень: junior · Роль: frontend · Категория: Технические вопросы

Компании: Kvando Technologies, IT-One, ООО Рокет Тех, DigitalSail, 1221 Systems

Стек: JavaScript

> Пример ответа

Короткий ответ

Всплытие (hoisting) - это механизм в JavaScript, при котором объявления переменных и функций перемещаются в начало их области видимости во время фазы компиляции, до выполнения кода. Это означает, что вы можете использовать переменную или вызывать функцию до её фактического объявления в коде. Однако важно помнить: всплывают только объявления, а не инициализации. Для var переменная будет undefined, для let и const - доступна, но в состоянии temporal dead zone.

Подробное объяснение

Hoisting работает на уровне компиляции: JavaScript-движок сначала сканирует код и регистрирует все объявления (var, let, const, function, class), а затем выполняет код. При этом:

  • var: объявление всплывает, инициализация остаётся на месте. До строки инициализации переменная равна undefined.
  • let и const: объявление всплывает, но переменная не инициализируется. До строки объявления доступ к ней вызывает ReferenceError из-за temporal dead zone (TDZ).
  • function declarations: полностью всплывают - и имя, и тело функции. Их можно вызывать до объявления.
  • function expressions: ведут себя как переменные - всплывает только имя переменной, но не присвоенная функция.
  • class declarations: не всплывают в практическом смысле - доступ до объявления вызывает ReferenceError.

Важно понимать, что hoisting - это не физическое перемещение кода, а модель поведения, которую описывает спецификация ECMAScript. Движок не двигает строки, а просто обрабатывает объявления до выполнения.

На практике

На практике hoisting чаще всего проявляется в двух сценариях:

  1. Использование var в функциях: если вы объявляете var внутри функции, она доступна во всей функции, даже до строки объявления. Это может привести к путанице, если вы не ожидаете такого поведения.

  2. Вызов function declaration до объявления: это легально и часто используется для организации кода - функции можно объявлять внизу модуля, а вызывать вверху.

Для let и const hoisting существует, но из-за TDZ он не даёт практического преимущества - доступ до объявления всегда ошибка. Поэтому в современном коде hoisting для переменных - это скорее источник ошибок, чем полезная фича.

Пример кода

JAVASCRIPT
// Пример 1: var
console.log(a); // undefined
var a = 5;
console.log(a); // 5
// Пример 2: let - TDZ
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
// Пример 3: function declaration
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
// Пример 4: function expression
console.log(sayBye); // undefined
sayBye(); // TypeError: sayBye is not a function
var sayBye = function() {
console.log("Bye!");
};
// Пример 5: порядок объявлений внутри функции
function test() {
console.log(x); // undefined
var x = 1;
console.log(y); // ReferenceError
let y = 2;
}

Как отвечать на собеседовании

Начните с краткого определения, затем приведите пример с var и function declaration. Обязательно упомяните разницу между var, let/const и TDZ. Если спросят про class - скажите, что они не всплывают. Хорошо добавить, что hoisting - это модель поведения, а не реальное перемещение кода. Для уровня junior достаточно уверенно объяснить базовые случаи и показать понимание, почему let/const безопаснее.

Что проверяет интервьюер

Интервьюер проверяет:

  • понимание разницы между объявлением и инициализацией;
  • знание поведения var, let, const в контексте hoisting;
  • понимание temporal dead zone;
  • умение объяснить, почему function declaration можно вызывать до объявления, а function expression - нет;
  • способность предсказать результат выполнения простого кода с hoisting.

Типичные ошибки

  • Утверждение, что let и const не всплывают - на самом деле всплывают, но с TDZ.
  • Смешивание hoisting с областью видимости: hoisting не меняет область видимости, только порядок доступности.
  • Ожидание, что var будет инициализирован значением до строки присваивания - на самом деле будет undefined.
  • Забывание, что class declarations не всплывают.
  • Путаница между function declaration и function expression - в expression всплывает только имя переменной, но не функция.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью