Facebook Pixel

Best Practices for Block Scope in JavaScript

Block scope is powerful. Here are the best practices to use it safely and avoid common pitfalls.

Best Practices for Block Scope in JavaScript

Block scope is one of the best features of modern JavaScript. Here are the best practices to use it well.

1. Use const by Default, let When Needed, Avoid var

const url = "https://api.example.com"; // will not change let count = 0; // will change `` `const` signals intent and prevents accidental reassignment. `let` is for variables that genuinely change. `var` is function-scoped and causes bugs. ### 2. Keep Variables in the Tightest Scope Possible ```js function process(data) { // bad: temp is in the whole function let temp; if (data.needsTransform) { temp = transform(data); use(temp); } // good: temp is only in the block that needs it if (data.needsTransform) { const temp = transform(data); use(temp); } } `` Tighter scope means fewer bugs and better garbage collection. ### 3. Use `let` in Loops, `const` in `for...of`/`for...in` ```js for (let i = 0; i < 3; i++) { ... } // counter changes, use let for (const item of items) { ... } // item does not change, use const for (const key in obj) { ... } // key does not change, use const `` ### 4. Wrap `switch` Cases in Braces ```js switch (x) { case 1: { const y = 1; break; } case 2: { const y = 2; break; } } `` Without braces, all cases share one scope, and re-declaring `let`/`const` throws. ### 5. Avoid Shadowing ```js // bad: confusing const name = "Kunal"; function greet() { const name = "Asha"; console.log(name); } // good: distinct names const globalName = "Kunal"; function greet() { const localName = "Asha"; console.log(localName); } `` If you must shadow, keep the scopes small and enable ESLint's `no-shadow` rule. ### 6. Do Not Close Over Large Objects Unnecessarily ```js // bad: keeps big alive function setup() { const big = new Array(1_000_000); return () => big.length; } // good: extract what you need function setup() { const big = new Array(1_000_000); const len = big.length; return () => len; } `` ### 7. Use Blocks for Temporary Variables ```js function process(data) { { const intermediate = transform(data); validate(intermediate); } // intermediate is freed here return finalize(data); } `` ### The Takeaway Use `const` by default, `let` for reassignable, avoid `var`. Keep variables in the tightest scope. Use `let` in classic `for`, `const` in `for...of`/`for...in`. Wrap `switch` cases in braces. Avoid shadowing. Do not close over large objects. Use blocks for temporary variables.

Use const by default and let for reassignable variables. Keep variables in the tightest scope possible. Use let in classic for loops, const in for...of and for...in. Wrap switch cases in braces. Avoid shadowing. Do not close over large objects unnecessarily.

Tighter scope means fewer bugs (variables are not visible where they are not needed), better garbage collection (variables are freed sooner), and more readable code (intent is clear).

Wrap each case in braces to give it its own block scope. Without braces, all cases share one scope, and re-declaring let or const with the same name throws SyntaxError.

Do not close over large objects unnecessarily. Extract what you need (e.g., const len = big.length; return () => len;) instead of closing over the whole object. Remove handlers when no longer needed.

Use let for classic for loop counters (they increment). Use const for for...of and for...in (each iteration is a fresh binding that does not change within the iteration). Never use var for loop variables in modern code.

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.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.