Illegal Shadowing in JavaScript Explained
Some shadowing is not allowed. Here is when shadowing throws a SyntaxError and why.
Illegal Shadowing in JavaScript Explained
Most shadowing is legal in JavaScript, but there is one case that throws a SyntaxError: shadowing a let (or const or class) with a var in the same scope.
The Illegal Case
let x = 1; { var x = 2; // SyntaxError: Identifier 'x' has already been declared } `` Why? `var` is function-scoped, so it ignores block boundaries. If this were allowed, the `var x` would leak out of the block and conflict with the outer `let x`. The engine catches this at parse time and throws. ### Why It Is Illegal The block `{}` does not create a new scope for `var`. So `var x` inside the block is the same scope as the outer `let x`. Two declarations of `x` in the same scope is a `SyntaxError`. ### The Legal Reverse ```js var x = 1; { let x = 2; // legal console.log(x); // 2 } console.log(x); // 1 `` Shadowing a `var` with a `let` is fine because `let` is block-scoped. It does not leak out, so there is no conflict with the outer `var`. ### Other Legal Shadowing ```js let x = 1; function foo() { let x = 2; // legal (function scope is separate) console.log(x); // 2 } foo(); console.log(x); // 1 `` ```js let x = 1; { let x = 2; // legal (block scope is separate) console.log(x); // 2 } console.log(x); // 1 `` Shadowing `let` with `let` (in a separate block or function scope) is fine. ### Shadowing `const` The same rules apply to `const`: ```js const x = 1; { var x = 2; // SyntaxError } `` ### Shadowing `class` ```js class Foo {} { var Foo = 1; // SyntaxError } `` ### The Rule You cannot use `var` to declare a variable that has the same name as a `let`, `const`, or `class` in the same (or an enclosing non-block) scope. This is because `var` leaks out of blocks and would create a conflict. ### The Takeaway Illegal shadowing: you cannot shadow a `let`, `const`, or `class` with a `var` in the same scope. `var` is function-scoped and leaks out of blocks, so it would conflict. The reverse (shadowing a `var` with a `let`) is legal. This is caught at parse time as a `SyntaxError`.
You cannot shadow a let, const, or class with a var in the same scope. var is function-scoped and leaks out of blocks, so it would conflict with the outer let/const/class. The engine throws SyntaxError: Identifier has already been declared.
Yes. Shadowing a var with a let is legal because let is block-scoped and does not leak out. There is no conflict. The reverse (shadowing a let with a var) is illegal.
Because var ignores block boundaries and would leak into the scope where the let is declared, creating two declarations of the same name in the same scope. The engine catches this at parse time.
Yes. Shadowing a const with a let (or another const) in a separate block or function scope is legal. The illegal case is only shadowing a let/const/class with a var in the same scope.
SyntaxError. The engine catches the duplicate declaration at parse time, before any code runs. The message is 'Identifier x has already been declared.'
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.

