Что такое hoisting в JavaScript?

JuniorJavaScript · Frontend·Обновлено 18 июня 2026
Коротко
Hoisting — это механизм JavaScript, при котором объявления переменных и функций как бы «поднимаются» в начало своей области видимости на этапе компиляции. Однако инициализация значений остаётся на своих местах, а поведение для var, let, const и function различается.

Что такое hoisting

Hoisting (поднятие) — это поведение движка JavaScript, при котором объявления (declarations) переменных, функций и классов обрабатываются до выполнения кода. Технически никакого физического «перемещения» строк не происходит: на этапе создания контекста выполнения движок проходит по коду и резервирует место в памяти для всех объявлений, а затем уже исполняет код построчно.

Именно поэтому к функции, объявленной через function, можно обратиться до её определения в исходном коде, а обращение к var-переменной до её объявления вернёт undefined, а не ошибку.

Как поднимаются разные сущности

var

Переменные, объявленные через var, поднимаются и инициализируются значением undefined. Поэтому обращение до объявления не выбрасывает ошибку.

console.log(x); // undefined
var x = 5;
console.log(x); // 5

Движок интерпретирует это примерно так:

var x; // объявление поднято и инициализировано как undefined
console.log(x);
x = 5;
console.log(x);

let и const

Объявления let и const также поднимаются, но не инициализируются. Переменная попадает во «временную мёртвую зону» (Temporal Dead Zone, TDZ) — от начала блока до строки объявления. Обращение к ней в этот момент вызывает ReferenceError.

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;

Function Declaration

Функциональные объявления поднимаются вместе с телом, поэтому их можно вызывать выше по коду.

greet(); // "Привет"

function greet() {
  console.log("Привет");
}

Function Expression и стрелочные функции

Функции, присвоенные переменной, подчиняются правилам этой переменной (var, let, const).

sayHi(); // TypeError: sayHi is not a function
var sayHi = function () {
  console.log("Hi");
};

Здесь поднимается только объявление var sayHi, а присвоение функции остаётся на своём месте.

class

Классы тоже поднимаются, но, как let/const, находятся в TDZ до момента объявления.

new User(); // ReferenceError
class User {}

Области видимости и hoisting

Важно понимать, что var имеет функциональную область видимости, а let и const — блочную. Поэтому поднятие var происходит до начала функции, а let/const — до начала ближайшего блока { ... }.

function demo() {
  console.log(a); // undefined
  if (true) {
    var a = 1;
    let b = 2;
  }
  console.log(a); // 1
  // console.log(b); // ReferenceError
}

Зачем это знать на практике

Понимание hoisting помогает избегать неочевидных багов: обращений к переменной до её инициализации, конфликтов имён, неожиданного undefined вместо ожидаемого значения. Современный стиль — использовать let и const, объявлять переменные как можно ближе к месту использования и не полагаться на поднятие var.

Что хочет услышать интервьюер

Чёткое определение hoisting и понимание, что поднимаются объявления, а не инициализации

Знание различий в поведении var, let, const, function declaration и class

Понимание Temporal Dead Zone и того, что let/const тоже поднимаются

Различие между function declaration и function expression при поднятии

Связь hoisting с областями видимости (функциональная для var, блочная для let/const)

Пример: Поднятие var и function declaration

// Обращение к функции до её объявления работает
sayHello();

function sayHello() {
  console.log("Привет, мир");
}

// var поднимается и инициализируется как undefined
console.log(count); // undefined
var count = 10;
console.log(count); // 10

Пример: Temporal Dead Zone у let и const

// Попытка обратиться к let до объявления вызовет ошибку
try {
  console.log(value); // ReferenceError
  let value = 42;
} catch (e) {
  console.log(e.message);
}

// const ведёт себя так же
{
  // здесь начинается TDZ для PI
  // console.log(PI); // ReferenceError
  const PI = 3.14;
  console.log(PI); // 3.14
}

Пример: Function declaration vs function expression

// Function Declaration — поднимается целиком
declared(); // "Я объявлена"
function declared() {
  console.log("Я объявлена");
}

// Function Expression — поднимается только var
try {
  expressed(); // TypeError: expressed is not a function
} catch (e) {
  console.log(e.message);
}
var expressed = function () {
  console.log("Я выражение");
};

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

Утверждение, что let и const вообще не поднимаются — они поднимаются, но в TDZ

Считать, что физически переносятся строки кода, а не происходит работа на этапе создания контекста

Путать поведение function declaration и function expression

Игнорировать разницу между функциональной и блочной областью видимости

Не упоминать, что var инициализируется значением undefined, а let/const — нет

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее