var a = 6;
{
console.log(a)
let a =55
}
when i execute this snippet I get following as error message: ReferenceError: Cannot access 'a' before initialization
why the console.log(a) is not giving 6 as result.
var a = 6;
{
console.log(a)
let a =55
}
when i execute this snippet I get following as error message: ReferenceError: Cannot access 'a' before initialization
why the console.log(a) is not giving 6 as result.
The nested block will create a new block scoped lexical environment.
The inner a
variable is declared in that scope, but accessed before the initialization, thus the error.
The inner scope let a
declaration overrides the var a
declaration, so it's a different variable, as if you wrote it like this:
var a = 6;
{
console.log(a2)
let a2 =55
}
.
To add to both above answers, the statement let a = 55
is actually two statements in one: let a
- a declaration - and a = 55
- an assignment. Because of Javascript's hoisting rules, the declaration is processed on entry to the block, but the assignment retains its lexical position.
So the block:
var a = 6
{
console.log(a)
let a = 55
}
is semantically equivalent to:
var a = 6
{
let a
console.log(a)
a = 55
}
Because the local declaration of a
masks the global variable of the same name, by the time console.log(a)
is executed a
has been declared but not yet assigned a value.
The answer to your question is in your title: the variable is in a "temporal dead zone", which is just a name for the behaviour you're seeing.
Take this explanation on MDN:
The start of the block is the opening
{
and yourconsole.log(a)
comes beforelet
statement, so it is in this "dead zone".Why does it work that way? Because it helps programmers detect bugs in their code caused by confusion between variables with the same name in different scopes.