When to Use let Instead of var in Javascript

javascript
Published on November 13, 2016

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
}

Using let in a for Loop

A for statement is of the form for (var i=0 ; ...) ... In most of the cases the iterator variable 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.

Using let in setTimeout / setInterval During a Loop

Using the iterator variable 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 the iterator variable and initializes to value it was assigned at the beginning of the loop. So basically each setTimeout() gets a copy of the iterator variable.

Same logic holds for for .. in loop.

Using let while Invoking Anonymous 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
In this Tutorial