Hoisting (Поднятие)
Перед выполнением кода JavaScript «сканирует» область видимости и регистрирует все объявления переменных и функций. Это и называется hoisting - объявления как будто «поднимаются» наверх.
Переменные
console.log(x) // undefined (не ошибка!)
var x = 5
console.log(x) // 5
// Движок интерпретирует это как:
var x // объявление поднято
console.log(x) // undefined
x = 5 // присваивание остаётся на месте
console.log(x) // 5
let и const тоже поднимаются, но попадают в TDZ (Temporal Dead Zone) - обращение до строки объявления кидает ReferenceError.
Function Declaration vs Function Expression
// ✅ Function Declaration - поднимается полностью
sayHi() // "Привет"
function sayHi() { console.log("Привет") }
// ❌ Function Expression - поднимается только переменная
greet() // TypeError: greet is not a function
var greet = function() { console.log("Привет") }
Function Declaration поднимается целиком (с телом). Function Expression - только объявление переменной (var greet = undefined).
Приоритеты при hoisting
console.log(typeof foo) // "function"
var foo = 1
function foo() {}
// Function Declaration имеет приоритет над var
Практический совет
Hoisting - источник неочевидных багов. Современная практика: объявляйте переменные в начале области видимости, используйте let/const вместо var, функции объявляйте до использования.