Scoping with var, let & const
var vs let vs const in JavaScript
var
var
has functional scope not block scope
1 | function foo() { |
variables defined with var keyword are not block scoped
1 | function foo() { |
- Variables declared with var keyword are hoisted.
1 | function foo() { |
The variable bar defined inside if block is visible to the outside block but within the function foo’s scope. This is because the JavaScript engine read the above code as following:
1 | function foo() { |
- Variables defined with var keywords can be redeclared in the same scope
1 | function foo() { |
let & const
- Variables declared with
let
&const
keyword are visible only inside the block in which it’s defined.
1 | function foo () { |
- Variables declared with
let
&const
keyword are not subjected to hoisting.
1 | function foo () { |
- Variables defined with
let
&const
keywords cannot be redeclared in the same block scope.
1 | function foo () { |
But a variable can be redeclared in function scope, given its declared within a different block scope.
1 | function foo () { |
Able to explain dead zone concept for [let]
accessing let and const values before they are initialized can cause a ReferenceError because of something called the temporal dead zone.
1 | console.log(aVar); // undefined |
It appears from these examples that
let
declarations (andconst
, which works the same way) may not be hoisted, sinceaLet
does not appear to exist before it is assigned a value.
That is not the case, however—
let
andconst
are hoisted (likevar
,class
andfunction
), but there is a period between entering scope and being declared where they cannot be accessed. This period is the temporal dead zone (TDZ).
The TDZ ends when
aLet
is declared, rather than assigned:
1 | let and const have two broad differences from var: |
This example shows that let
is hoisted:
1 | let x = 'outer value'; |
Accessing x
in the inner scope still causes a ReferenceError
. If let
were not hoisted, it would log outer value
.
The TDZ is a good thing because it helps to highlight bugs—accessing a value before it has been declared is rarely intentional.