I have the following code. The only interesting part is that I redeclare productId
in the second switch case.
let productId = 1;
const check = true;
switch (check) {
case false:
console.log(productId);
break;
case true:
let productId = 2;
console.log(productId);
break;
}
If I set check
to true
, then the code works correctly and prints
2
If I set check
to false
, then the code gives a ReferenceError
/home/osama/workspace/test/javascript.js:7
console.log(productId);
^
ReferenceError: productId is not defined
at Object.<anonymous> (/home/osama/workspace/test/javascript.js:7:21)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
If I use var
to declare productId
then the code works correctly regardless of the value of check
.
I realize that the let/const
statement is shadowing the global variable in someway, but my question is:
Why does the declaration of a variable inside a switch statement, cause the global variable to become undefined and throw a ReferenceError
?
Hoisting and Temporal Dead Zone!
let
and const
get hoisted to the nearest block, so it becomes something like this:
switch (check) {
let productId;
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
and thus because of temporal dead zone
, the ReferenceError comes up