Skip to main content

Understanding Variable Shadowing in JavaScript

Variable Shadowing occurs when a variable declared within a specific scope (like a function or a block) has the same name as a variable in an outer scope.

When this happens, the inner variable "shadows" the outer one, making the outer variable inaccessible within that specific inner block.

How Shadowing Works

In the example below, notice how the city inside the function is independent of the city defined at the top level.

Example: Lexical Shadowing
JavaScript Runtime
Console Output

What's happening? > The city parameter on Line 3 shadows the city variable on Line 1. Any changes made to city inside the function (Line 4) stay inside the function's "bubble."

The Rules of Shadowing

While shadowing is a common pattern, JavaScript has strict rules about how different declaration types (var, let, const) interact across scopes.

1. Illegal Shadowing

You cannot shadow a let or const variable using var within the same block or a nested block. This is because var is function-scoped and tries to "hoist" itself to the top, which conflicts with the block-scoped let.

Error: Illegal Shadowing Attempt
JavaScript Runtime
Console Output

The var at line 4 is trying to 'cross the boundary' of the let declaration, which results in a SyntaxError.

2. Valid Shadowing (Function Boundaries)

Shadowing becomes valid again if there is a function boundary separating the declarations. Since functions create a completely new execution context, the conflict is resolved.

Valid: Shadowing via Function Boundary
JavaScript Runtime
Console Output

Best Practices

  • Avoid Name Collision: While shadowing is technically allowed, using the same name for different variables can lead to "Silent Bugs" that are hard to debug.
  • Be Specific: Instead of shadowing data, use more descriptive names like userData and filteredData.