Facebook Pixel

Shadowing in JavaScript: A Complete Guide

Shadowing is when an inner variable hides an outer one. Here is how it works, when it is legal, and when it is not.

Shadowing in JavaScript: A Complete Guide

Shadowing happens when a variable in an inner scope has the same name as a variable in an outer scope. The inner one shadows (hides) the outer one within its scope.

How Shadowing Works

const name = "Kunal"; function greet() { const name = "Asha"; // shadows the outer name console.log(name); // "Asha" } greet(); console.log(name); // "Kunal" (outer is unchanged) `` Inside `greet`, `name` resolves to the local one. The engine finds it first in the scope chain and stops. The outer `name` is hidden but not affected. ### Shadowing With `var` and Hoisting ```js var x = 1; function foo() { console.log(x); // undefined (not 1!) var x = 2; console.log(x); // 2 } foo(); console.log(x); // 1 `` The inner `var x` is hoisted to the top of `foo` with `undefined`, shadowing the outer immediately. The first log sees `undefined`, not the outer value. This is a common interview trap. ### Block-Scoped Shadowing ```js let x = 1; if (true) { let x = 2; // shadows the outer x in this block console.log(x); // 2 } console.log(x); // 1 `` `let` and `const` can shadow in blocks too. This is legal and sometimes useful, but can be confusing. ### Illegal Shadowing ```js let x = 1; { var x = 2; // SyntaxError: Identifier 'x' has already been declared } `` You **cannot** shadow a `let` with a `var` in the same scope. `var` ignores block boundaries, so it would leak out and conflict. But the reverse is fine: ```js var x = 1; { let x = 2; // legal (let is block-scoped, does not conflict with the outer var) } `` ### Shadowing Across Functions ```js function outer() { const x = 10; function inner() { const x = 20; // shadows outer's x console.log(x); // 20 } inner(); console.log(x); // 10 } outer(); `` ### Shadowing and Arrow Functions Arrow functions follow the same block scope rules. An arrow can shadow an outer variable: ```js const x = 1; const foo = () => { const x = 2; console.log(x); // 2 }; foo(); `` ### When Shadowing Is Useful - **Loop bodies**: the loop variable shadows any outer variable with the same name. - **Callbacks**: a parameter name can shadow an outer variable without conflict. - **Local helpers**: a short-lived variable can reuse a common name like `i` or `item`. ### When Shadowing Is Dangerous - **Readability**: shadowed names confuse readers. They have to track which `x` is which. - **Bugs**: `var` shadowing + hoisting causes the "undefined instead of outer value" bug. - **Maintenance**: renaming the outer variable does not update the inner shadow, leading to stale code. ### Best Practices - Use distinct names when possible. - If you must shadow, keep the scopes small (blocks, not whole functions). - Avoid shadowing with `var` (the hoisting bug). - Linters like ESLint have `no-shadow` rules to catch unwanted shadowing. ### The Takeaway Shadowing is when an inner variable hides an outer one with the same name. The inner wins; the outer is unaffected but hidden. `var` shadowing + hoisting causes bugs. Shadowing a `let` with a `var` in the same scope is illegal. Use distinct names for clarity; enable ESLint's `no-shadow` rule.

When a variable in an inner scope has the same name as a variable in an outer scope. The inner one shadows (hides) the outer one within its scope. The outer variable is not affected; it is just hidden.

Because the inner var is hoisted to the top of the function with undefined, shadowing the outer immediately. A read before the assignment line sees undefined, not the outer value. This is a common interview trap.

No. It throws SyntaxError: Identifier 'x' has already been declared. var ignores block boundaries, so it would leak and conflict. Shadowing a var with a let is fine, but not the reverse.

No. The outer variable is unchanged. Shadowing only hides it within the inner scope. Once the inner scope ends, the outer variable is visible again with its original value.

Generally no, for readability. Shadowed names can confuse readers and cause bugs (especially with var hoisting). Use distinct names, keep scopes small if you must shadow, and enable ESLint's no-shadow rule.

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.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.