Block Scope with let and const: Examples
Block scope confines let and const to their braces. Here are practical examples including loops and conditionals.
Block Scope with let and const: Examples
Block scope means let and const are only accessible inside the nearest pair of braces {}. Here are practical examples.
Basic Block Scope
{ const x = 1; let y = 2; console.log(x, y); // 1 2 } console.log(x); // ReferenceError console.log(y); // ReferenceError `` ### `if` Blocks ```js if (true) { const message = "yes"; let count = 1; } console.log(message); // ReferenceError console.log(count); // ReferenceError `` `var` would leak out of the `if`. `let` and `const` stay inside. ### `for` Loops ```js for (let i = 0; i < 3; i++) { const item = items[i]; console.log(item); } console.log(i); // ReferenceError console.log(item); // ReferenceError `` Both `i` and `item` are confined to the loop body. With `var i`, it would leak. ### `for...of` and `for...in` ```js for (const item of [1, 2, 3]) { console.log(item); } for (const key in { a: 1, b: 2 }) { console.log(key); } `` `const` works here because each iteration creates a fresh binding. ### `try...catch` ```js try { throw new Error("oops"); } catch (err) { // err is block-scoped to the catch block console.log(err.message); } console.log(err); // ReferenceError `` The `catch` parameter is block-scoped. ### Nested Blocks ```js { const a = 1; { const b = 2; console.log(a, b); // 1 2 (inner can see outer) } console.log(b); // ReferenceError (outer cannot see inner) } `` Inner blocks can see outer block-scoped variables. Outer blocks cannot see inner ones. ### Shadowing in Blocks ```js let x = 1; { let x = 2; // shadows the outer x console.log(x); // 2 } console.log(x); // 1 `` Block-scoped shadowing is legal and sometimes useful, but use distinct names for clarity. ### The Takeaway `let` and `const` are block-scoped: confined to their braces. This applies to `if`, `for`, `for...of`, `try...catch`, and plain blocks. Inner blocks can see outer; outer cannot see inner. Use `const` for loop bindings that do not change (`for...of`), `let` for incrementing counters.
Variables declared with let and const are only accessible inside the nearest pair of braces. This applies to if blocks, for loops, try/catch, and plain blocks. var is not block-scoped and leaks out.
Yes. Each iteration of for...of creates a fresh binding, and the loop variable does not change within an iteration. Use const for for...of and for...in. Use let only for classic for loops where the counter increments.
No. let is block-scoped, so the loop variable stays inside the loop. var is function-scoped and leaks out, which is one reason to prefer let in loops.
Yes. The err in catch (err) is block-scoped to the catch block. It is not accessible outside the catch, and it does not leak to the outer scope.
Yes. Inner blocks can access outer block-scoped variables via the scope chain. But outer blocks cannot see inner block-scoped variables. This is the same as function scope nesting.
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

