Learn the concept
Scope & Scope Chain
Function scope (var) means a variable is accessible throughout the entire function it's declared in. Block scope (let/const) limits a variable to the nearest enclosing block (if, for, while, or bare {}). Block scoping prevents common bugs like loop variable leaking and accidental overwrites.
Function Scope (var):
undefinedundefined)Block Scope (let / const):
{}ReferenceErrorconst additionally prevents reassignment (but does NOT make objects immutable)The Classic Loop Problem:
var in a for-loop creates a single variable shared across all iterationslet creates a fresh binding per iteration, fixing this naturallyScope Chain:
Best Practice:
const for values that won't be reassignedlet when reassignment is neededvar in modern code — block scoping prevents an entire class of bugsfunction example() {
// var is function-scoped — accessible throughout the function
if (true) {
var x = 10;
let y = 20;
const z = 30;
}
console.log(x); // 10 — var leaks out of the if-block
// console.log(y); // ReferenceError — let is block-scoped
// console.log(z); // ReferenceError — const is block-scoped
// var hoisting — accessible before declaration
console.log(a); // undefined (hoisted, initialized as undefined)
var a = 5;
// let/const TDZ — NOT accessible before declaration
// console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 5;
}Block scoping with let/const prevents loop counters, temporary variables, and intermediate values from polluting the enclosing function scope
Using let in loops that attach event handlers ensures each handler captures its own iteration value
Using const for configuration prevents accidental reassignment while still allowing property updates via mutation
Build a tool that takes JavaScript code and visually highlights different scope levels and variable accessibility
Create an interactive quiz that presents var/let scoping puzzles and explains the output