I mistakenly wrote a re-declaration of an argument as a const
in a function and instead of throwing SyntaxError: Identifier \'bar\' has already been decla
Because const
declarations are block scoped, the const bar
declaration gets hoisted to the start of the block. (Just after try {
)
That means that bar
isn't actually defined when you try to log it, because the hoisting overrides / hides the parameter bar
.
It's a myth that const
and let
aren't hoisted at all. They're half-hoisted. :-) That is: Within a block, if const bar
or let bar
(or class bar { }
for that matter) appears anywhere in that block, then bar
cannot be used prior to that declaration in the block — even if it exists in a containing scope. This area between the beginning of the block and the declaration is called the Temporal Dead Zone:
function foo(bar) {
// `bar` is fine here
try {
// Temporal Dead Zone, `bar` cannot be used here
console.log(bar);
// End of TDZ
const bar = 123;
// `bar` would be fine here
} catch(err) { console.log(err) }
}
foo(456);
Taken from here https://tylermcginnis.com/videos/var-let-const/
var is function scoped and if you try to use a variable declared with var before the actual declaration, you'll just get undefined. const and let are blocked scoped and if you try to use a const or let variable before the declaration you'll get a reference error.
Constants are block-scoped, much like variables defined using the let statement.
From this MDN article.
Since you wrapped bar
inside a block of braces, its definition is relative to that block. And because you have another bar
declaration inside of that block, despite being after the call to it, the compiler will attempt to use this newly defined bar
instead of the passed-in parameter. Rename them as separate parameters to mitigate confusion, since one can assume they are holding different data because of your declaration.