Hoisting
Hoisting is JavaScript's behavior of moving declarations to the top of their scope during the creation phase.
Variable Hoisting
var — Hoisted & initialized to undefined
console.log(a); // undefined (not ReferenceError)
var a = 10;
console.log(a); // 10
let / const — Hoisted but NOT initialized (TDZ)
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
The time between entering the scope and the declaration is called the Temporal Dead Zone (TDZ).
{
// TDZ starts
console.log(x); // ReferenceError
let x = 5; // TDZ ends
}
Function Hoisting
Function Declarations — Fully hoisted
greet(); // "Hello!" — works because the entire function is hoisted
function greet() {
console.log("Hello!");
}
Function Expressions — NOT hoisted
greet(); // TypeError: greet is not a function
var greet = function () {
console.log("Hello!");
};
// 'greet' is hoisted as undefined (var), but the function assignment is NOT
Arrow Functions — Same as expressions
greet(); // TypeError: greet is not a function
var greet = () => console.log("Hello!");
Summary Table
| Declaration | Hoisted? | Initialized? | TDZ? |
|---|---|---|---|
var | ✅ | undefined | ❌ |
let | ✅ | ❌ | ✅ |
const | ✅ | ❌ | ✅ |
| Function Declaration | ✅ | Full body | ❌ |
Function Expression (var) | ✅ | undefined | ❌ |
Arrow Function (const) | ✅ | ❌ | ✅ |
Key Takeaways
- All declarations are hoisted, but only
varand function declarations are initialized. letandconsthave a Temporal Dead Zone — you can't use them before their declaration.- Function declarations are hoisted with their body; function expressions are not.
- To avoid confusion, declare variables at the top of their scope.