1. Introduction
In this tutorial, we’ll discuss another way for declaring variables in JavaScript. First we have to discuss the problem with var
which lead to the need of let
.
var x = 5; if (true) { var x = 2; console.log(x); //output: 2 } console.log(x); //output: 2
In this code, x is changed in the if block and it overrides the value of x declared outside the if block. To overcome such problems, a block-scoped variable was required.
The let
allows you declare a block-scoped local variable. You can initialize it to a value if you want to.
let x = 5; if (true) { let x = 2; console.log(x); //output: 2 } console.log(x); //output: 5
let
allows you to declare a block-level declaration. Block-level declarations are not accessible outside a given block. Block scopes are created in the following places:
- inside a function.
- inside a block (enclosed between { and })
A let
variable’s scope is limited to only the current code block. One important point to note about let
is that it is only initialized only when the initialization statement is executed. This behavior is different from that of var
which is hoisted and initialized to the default value of undefined
.
2. let
does not create properties of the window
object when declared globally
let y = 5; console.log(window.y); // output is undefined console.log(this.y); //output is undefined
3. let
is a block-scoped variable
The scope of a let
variable is the block in which they are declared as well as any sub-blocks in the block. You saw an example of let
as a block-scoped variable. Following is an example of let
which is similar to var
where let
has scope of enclosing variables as well.
function test() { let x = "inside function"; { x = "inside block"; console.log(x); //inside block } console.log(x); //inside block }
4. You can’t redeclare same let
variable in the block
Redeclaring same let
variable in the same block raises SyntaxError
.
function hello() { let x = "hello"; let x = "world"; // SyntaxError }
5. let
Hoisting
Variables declared with let
are also hoisted but not initialized with a default value. An exception will be thrown if you try to read a let
variable before it is initialized.
console.log(str); // Throws ReferenceError exception let str = 'hello'; // Initialization
6. Redeclaring same var
variable as let
Since var
variables are hoisted, you’ll get SyntaxError
in the following example:
let x = 5; { var x = 6; // SyntaxError for re-declaration }
7. Temporal dead zone (TDZ)
We already discussed that a let
variable can’t be read until they are fully initialized. A variable is in temporal dead zone (TDZ) from the start of the block until it is fully initialized. The term “temporal” is used because it depends on the execution of the code rather than the order in which the code is written.
{ // TDZ for x starts here at the beginning of the block console.log(x); //reference error console.log('hello world'); let x = 5; // TDZ ends here for x as it is initialized }
Another example:
{ // TDZ starts here at beginning of scope const myFunc = () => console.log(myVar); // no exception // Read/write of myVar will thow throw ReferenceError let myVar = 5; // TDZ for myVar ends here myFunc(); // myFunc() is called outside TDZ }
Within the TDZ accessing a
let
variable access throws ReferenceError.
7.1 typeof in TDZ
Using typeof
operator for a let
variable in its TDZ will throw a ReferenceError
.
console.log(typeof i); // throws a 'ReferenceError' let x = 'hello';
8. Conclusion
In this tutorial, we discussed let
, the way to declare block-scoped variables. It is recommended to use let
instead of var
as it is more clearer to use let
and readability.