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

Как работает Hoisting в JavaScript?

1.3 Junior🔥 241 комментариев
#JavaScript Core#Браузер и сетевые технологии

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

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

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

Полный механизм Hoisting в JavaScript

1. Жизненный цикл Execution Context

JavaScript создаёт Execution Context с двумя фазами:

// Фаза 1: Creation Phase
// - Создаются переменные (undefined для var)
// - Функции полностью загружаются в память
// - Устанавливается значение this

// Фаза 2: Execution Phase
// - Выполняется код строка за строкой
// - Переменным присваиваются значения

// Пример
console.log(x); // Phase 1: x создана как undefined
var x = 5;      // Phase 2: x = 5
console.log(x); // Phase 2: 5

2. Hoisting для var, let, const

Все три всплывают, но по-разному:

// VAR: объявление + undefined инициализация
console.log(a); // undefined (не ошибка)
var a = 1;

// LET/CONST: объявление БЕЗ инициализации (TDZ)
console.log(b); // ReferenceError
let b = 2;

// Внутри интерпретируется так:
// var a; (объявление) + undefined
// // TDZ для b начинается
// console.log(a); // undefined
// let b; (в конце TDZ присвоение)

3. Temporal Dead Zone (TDZ)

Zone между началом области видимости и инициализацией переменной:

function example() {
  console.log(x); // ReferenceError: Cannot access x before initialization
  // <- TDZ для x находится здесь
  let x = 5;     // <- Конец TDZ, x инициализирована
  console.log(x); // 5
}

example();

4. Hoisting функций

Function declarations полностью всплывают:

// Функция полностью загружена в фазе Creation
console.log(greet('John')); // 'Hello John'

function greet(name) {
  return `Hello ${name}`;
}

// Function expressions — нет
console.log(hello('John')); // TypeError: hello is not a function

var hello = function(name) {
  return `Hello ${name}`;
};

5. Hoisting в различных scopes

// GLOBAL SCOPE
var globalVar = 'global';

function outer() {
  // FUNCTION SCOPE
  var functionVar = 'function';
  
  if (true) {
    // BLOCK SCOPE (для let/const)
    let blockVar = 'block';
  }
  
  // Все var хоистятся в верх функции
  console.log(functionVar); // 'function'
}

// var хоистится в global scope
console.log(typeof globalVar); // 'string'

6. Практический пример: сложный случай

console.log(typeof x); // 'undefined' (hoisted)
console.log(typeof y); // 'undefined' (hoisted)

if (true) {
  var x = 1;
  let y = 2;
}

console.log(x); // 1 (function scope)
console.log(typeof y); // 'undefined' (block scope)

// JavaScript видит это так:
// var x;
// let y; // TDZ begins
// if (true) {
//   x = 1;
//   y = 2; // TDZ ends
// }

7. Классы тоже попадают в TDZ

console.log(typeof MyClass); // ReferenceError
// <- TDZ для MyClass

class MyClass {
  constructor() {}
}

// Даже наследование:
class Child extends Parent {} // ReferenceError
class Parent {}

8. Почему это важно знать

// Частая ошибка
var x = 1;

function test() {
  console.log(x); // undefined, а не 1!
  var x = 2;
}

test();

// Эквивалентно:
function test() {
  var x;
  console.log(x); // undefined (var x объявлена ниже)
  x = 2;
}

Hoisting — это фундаментальный механизм JavaScript. Понимание его критично для избежания неожиданного поведения и написания предсказуемого кода.

Как работает Hoisting в JavaScript? | PrepBro