← Назад к вопросам

Всплывает ли const

1.7 Middle🔥 231 комментариев
#HTML и CSS

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Всплывает ли const

Хойстинг (hoisting) — это поведение JavaScript, когда объявления переменных и функций перемещаются в верх их области видимости. Вопрос о const и хойстинге часто путают, и нужно понимать тонкости.

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

Технически yes, const всплывает, но не работает как var. Переменные, объявленные с const, помещаются в Temporal Dead Zone (TDZ) и недоступны до момента объявления.

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

1. Что происходит с const при хойстинге

// Этот код вызовет ошибку!
console.log(x); // ReferenceError: Cannot access 'x' before initialization

const x = 5;
console.log(x); // 5

Что происходит внутри JavaScript:

// Фаза 1: Создание - const создается и помещается в TDZ
// x существует, но в Temporal Dead Zone

// Фаза 2: Выполнение
console.log(x); // Ошибка! x еще в TDZ

const x = 5; // Только здесь x выходит из TDZ

2. Сравнение с var и let

var — всплывает и инициализируется как undefined:

console.log(a); // undefined (не ошибка!)

var a = 5;
console.log(a); // 5

// Так видит JavaScript:
// var a;
// console.log(a); // undefined
// a = 5;

let и const — всплывают, но в Temporal Dead Zone:

console.log(b); // ReferenceError
let b = 5;

console.log(c); // ReferenceError
const c = 5;

// И let, и const помещаются в TDZ
// Они технически "всплывают", но не инициализируются

Что такое Temporal Dead Zone (TDZ)

TDZ — это период от начала области видимости до строки объявления переменной:

{
  // НАЧАЛО TDZ для x
  console.log(x); // ReferenceError
  
  let x = 5;
  // КОНЕЦ TDZ для x
  
  console.log(x); // 5
}

Визуально:

{
  // <<<--- TEMPORAL DEAD ZONE --->>>
  // x существует (хойстинг), но недоступна
  console.log(typeof x); // ReferenceError (не "undefined"!)
  
  const x = 5; // <<<--- Здесь TDZ заканчивается
  
  console.log(x); // 5
}

Практические примеры

Пример 1: Классический случай ReferenceError

function example() {
  console.log(myVar); // ReferenceError!
  const myVar = 'hello';
}

example(); // ReferenceError: Cannot access 'myVar' before initialization

Пример 2: Область видимости блока

console.log(x); // ReferenceError

if (true) {
  const x = 5;
  console.log(x); // 5
}

console.log(x); // ReferenceError - x не существует в глобальной области

Пример 3: Функциональная область видимости

function outer() {
  console.log(y); // ReferenceError
  
  function inner() {
    const y = 10;
  }
  
  inner();
}

outer(); // ReferenceError

Пример 4: typeof не спасает

Осторожно! typeof не спасает от ReferenceError для const в TDZ:

// typeof ДО объявления переменной
console.log(typeof undeclaredVar); // "undefined" - переменная не существует
console.log(typeof x); // ReferenceError - x в TDZ!

const x = 5;

Вот почему:

  • undeclaredVar — переменная вообще не существует, typeof возвращает "undefined"
  • x — переменная СУЩЕСТВУЕТ (хойстинг), но в TDZ, typeof вызовет ошибку

Пример 5: Цикл и блок видимости

for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 0, 1, 2
  }, 0);
}

// Почему работает?
// let создается новая переменная для каждой итерации (блок видимости)
// const работает также

for (const j of [1, 2, 3]) {
  console.log(j); // 1, 2, 3
}

Почему это важно

// ПЛОХО - полагаться на хойстинг
function processUser(user) {
  if (user.isAdmin) {
    const adminToken = getAdminToken();
    doAdminAction(adminToken);
  }
  
  // Разработчик ошибочно использует adminToken здесь
  console.log(adminToken); // ReferenceError (хорошо, ловит ошибку!)
}

// ХОРОШО - объявлять в нужном месте
function processUser(user) {
  const adminToken = null; // явно в начале функции если нужно везде
  
  if (user.isAdmin) {
    adminToken = getAdminToken(); // или только локально в блоке
    doAdminAction(adminToken);
  }
}

Сравнительная таблица

Характеристикаvarletconst
ХойстингДаДа (TDZ)Да (TDZ)
Инициализацияundefinedне инициализируетсяне инициализируется
Область видимостиФункцияБлокБлок
ПереассигнениеДаДаНет
TDZНетДаДа
ReferenceError до объявленияНетДаДа

Вывод

const всплывает, но не работает как var.

Основные моменты:

  1. Все переменные всплывают — это часть фазы создания JavaScript движка
  2. var всплывает и инициализируется как undefined, поэтому доступна с undefined значением
  3. let и const всплывают в TDZ — они существуют, но недоступны до строки объявления
  4. Это вызывает ReferenceError — не "undefined", а полную ошибку
  5. TDZ длится от начала блока до строки объявления — это защищает от ошибок

Используй const и let вместо var — они защищают от ошибок, связанных с хойстингом, благодаря TDZ.