JavaScript · Question 72
How can lexical shadowing create a Temporal Dead Zone even when an outer variable has the same name?
Direct answer
A let, const, or class declaration creates a binding for its entire lexical scope, so that binding shadows an outer variable from the start of the scope even though it cannot be accessed before initialization.
let value = "outer";
{
console.log(value);
let value = "inner";
}ReferenceError: Cannot access 'value' before initialization
Consider let value = "outer"; { console.log(value); let value = "inner"; }. The console.log does not fall back to the outer value. The block already has its own lexical binding named value, and that binding is still uninitialized at the log statement. The result is a ReferenceError.
This demonstrates why the TDZ is not simply “the lines between entering the block and the declaration.” The key is that the binding already exists for scope resolution, but accessing it before the declaration is evaluated is forbidden.
- Shadowing chooses the nearest lexical binding.
- The existence of an outer initialized variable does not bypass the inner TDZ.
- The same reasoning is important when refactoring large blocks and adding a new
letorconstdeclaration with an existing name.