When to Use let Instead of var in Javascript

Both var and let are used to define variables. The only difference is in the scope they provide for variables defined using them. Scope of a variable, in simple terms is the section of code where the variable is visible. Outside its scope, the variable does not exist.

Declaration of variables with var

A variable defined using var is known throughout the function it is defined in.

function doSomething() { // x is know throughout this function var x = 0; // rest of the code }

If the variable is defined outside a function, it means it is a global variable and has global scope. It is known throughout the whole code.

Declaration of variables with let

A variable defined using let is known only in the block it is defined in. The scope of this variable is its block.

A block basically means a section of code within curly braces { .. }. For example a function is defined is defined within a { .. }. Similarly a "for" loop is defined within a { .. }.

In case you don't know, you can add any section of your code within a block - no errors will be thrown. This feature was added in ES6.

But outside the scope of the block, the variable defined using let will not be visible.

function doSomething() { { let temp = 123; } console.log(temp); // Reference Error: temp is not defined }

The classic use of let is in " for " loop

A for statement is of the form for (var i=0 ; ...) ... In most of the cases the iterator variable " i " is not required after the for loop.

function some_function() { for(var i=0; i<5; i++) { // something } // i is visible here, although of no use console.log(i) }

If we use let in the for loop, the iterator variable will not exist beyond the for loop.

function some_function() { for(let i=0; i<5; i++) { // something } // i is not visible here, will throw an error console.log(i) }

let can also be used in for .. in loop for traversing objects.

let can be used to avoid closure issues such as using setTimeout or setInterval in " for " loop

Using the iterator variable " i " in setTimeout function defined inside for loop is tricky.

for(var i=0; i<5; i++) { setTimeout(function() { console.log(i) // i will be 5 in all }, 1000); }

You may solve this by passing an extra parameter to setTimeout().

for(var i=0; i<5; i++) { setTimeout(function(i) { console.log(i) // i will be 0, 1, 2, 3, 4 }, 1000, i); }

But using let is the best option. In this case, i will not be stored as a reference variable in setTimeout. It is passed by value - the exact value will be stored.

for(let i=0; i<5; i++) { setTimeout(function() { console.log(i) // i will be 0, 1, 2, 3, 4 }, 1000); }

This happens because with each iteration of the loop, let creates a new copy of "i" and initializes to value it was assigned at the beginning of the loop. So basically each setTimeout() gets a copy of the variable "i".

Same logic holds for for .. in loop.

let can be used instead of Immediately Invoked Functions

Immediately Invoked Function Expressions (IIFE) are used to invoke an anonymous function immediately. The main advantage is that after the execution of the function, variables defined in it cease to exist. So global space is left unpolluted.

(function () { var a=5, b=7; // do things​ with a & b })(); // a & b are not visible in the rest of the code

An alternate solution to this is using let variables within a block. The only advantage is that is looks neat.

// added in global code { let a=5, b=7; // do things with a & b } // a & b are not visible in the rest of the code