Variable Hoisting: var vs let vs const
EasyHoisting is JavaScript's behavior of moving declarations to the top of their scope during the compilation phase. All variable declarations (var, let, const) are hoisted, but they behave very differently: var is initialized with undefined, while let and const are not initialized, creating the Temporal Dead Zone (TDZ). Understanding this difference is crucial for interview success.
Interactive Visualization
1console.log(x); // ???2var x = 5;3console.log(x); // ???
Key Points
- All declarations are hoisted to the top of their scope during compilation
- var declarations are hoisted AND initialized with undefined
- let and const declarations are hoisted but NOT initialized
- Accessing let/const before declaration throws ReferenceError (TDZ)
- typeof an undeclared variable returns "undefined", but typeof in TDZ throws
- const must be initialized at declaration time
Code Examples
var Hoisting - Initialized with undefined
console.log(x); // undefined (not an error!) var x = 5; console.log(x); // 5 // JavaScript interprets this as: // var x; // Declaration hoisted, initialized undefined // console.log(x); // undefined // x = 5; // Assignment stays in place // console.log(x); // 5
var is hoisted and automatically set to undefined. No error when accessing before declaration.
let Hoisting - NOT Initialized (TDZ)
// console.log(y); // ❌ ReferenceError! Cannot access before initialization let y = 10; console.log(y); // 10 // let IS hoisted, but not initialized // The variable exists but has no value until declaration line
let is hoisted but not initialized. Accessing it before declaration is the Temporal Dead Zone.
const Hoisting - Same as let
// console.log(z); // ❌ ReferenceError! TDZ const z = 20; console.log(z); // 20 // const z; // ❌ SyntaxError! Must initialize // const z = 20; // ✅ Correct
const behaves like let for hoisting, but must be initialized at declaration
typeof Behavior - Key Difference
// Undeclared variable console.log(typeof undeclaredVar); // "undefined" (no error!) // TDZ variable // console.log(typeof tdzLet); // ❌ ReferenceError! let tdzLet = 5; // This proves let IS hoisted - typeof knows it exists!
typeof behaves differently: undeclared = "undefined", TDZ = ReferenceError. This proves let IS hoisted.
Function Scope Hoisting with var
function demo() { console.log(a); // undefined if (true) { var a = "I'm var in a block"; } console.log(a); // "I'm var in a block" } demo();
var is hoisted to the function scope, not block scope. It leaks out of the if block.
Common Mistakes
- Thinking let/const are NOT hoisted (they are, just not initialized)
- Using variables before declaration and relying on hoisting
- Confusing the TDZ error with "variable not defined"
- Forgetting that var hoists to function scope, not block scope
Interview Tips
- Emphasize: ALL declarations are hoisted, initialization behavior differs
- Use the typeof test to prove let/const are hoisted
- Explain that TDZ is a ReferenceError, not undefined
- Know that var hoists with undefined, let/const don't initialize