🎈

Hoisting

beginner

Hoisting is JavaScript's default behavior of moving declarations to the top of their scope before code execution. Understanding hoisting helps you predict how variables and functions behave before they're defined in your code.

🎮Interactive Visualization

CodeCreation Phase
1console.log(x); // ???
2var x = 5;
3console.log(x); // ???
Global Execution Context
Variable Environment
xundefinedhoisted
Output
Step 1/4Global EC created. JS scans for declarations and hoists var x to the top with value undefined
Hoisted (undefined)
TDZ (cannot access)
Initialized

Key Points

  • Variable declarations (var) are hoisted, but not their assignments
  • Function declarations are fully hoisted (name + body)
  • let and const are hoisted but stay in the "Temporal Dead Zone" until declared
  • Function expressions are NOT hoisted like function declarations

💻Code Examples

var Hoisting

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

// JS interprets as:
// var x;
// console.log(x);
// x = 5;

var declarations are hoisted, but not assignments

Function Declaration

sayHi();  // "Hello!"

function sayHi() {
  console.log("Hello!");
}

// Works because function
// declarations are fully hoisted

Function declarations are fully hoisted

let & TDZ

console.log(x);  // ReferenceError!
let x = 5;

// let/const are hoisted but
// remain in "Temporal Dead Zone"
// until the declaration line

let/const have Temporal Dead Zone

var vs let in Loops

// var - shared across iterations
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i));
}
// Output: 3, 3, 3

// let - new binding each iteration
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i));
}
// Output: 0, 1, 2

Different scoping behaviors

Function Expressions

sayHi();  // TypeError!

var sayHi = function() {
  console.log("Hello!");
};

// Only the variable declaration
// is hoisted, not the function

Expressions are NOT hoisted like declarations

Mixed Declarations

console.log(a);  // undefined
console.log(b);  // ReferenceError
console.log(c);  // [Function: c]

var a = 1;
let b = 2;
function c() {}

Understanding declaration order

var Redeclaration

var x = 1;
var x = 2;  // OK with var
console.log(x);  // 2

let y = 1;
let y = 2;  // SyntaxError!
// Cannot redeclare with let

var allows redeclaration, let does not

Block Scope

if (true) {
  var a = 1;   // function-scoped
  let b = 2;   // block-scoped
}
console.log(a);  // 1
console.log(b);  // ReferenceError!

// let/const respect {} blocks
// var ignores them

let/const are block-scoped

Common Mistakes

  • Assuming let/const don't hoist (they do, but have TDZ)
  • Using var in loops and expecting block scope
  • Relying on hoisting instead of declaring variables at the top

Interview Tips

  • Explain the difference between declaration and initialization
  • Know what TDZ means and when it applies
  • Be able to predict output of hoisting quiz questions

🔗Related Concepts