Tuesday, July 23, 2013

Closure in JavaScript

What is Closure

To understand the closure in JavaScript seems to be difficult, but not really. Let’s understand the concept step by step.

The Closure is a function which has access to variables of its outer function, that’s it, Is not this awesome? Let’s dive into the example

	var color = "red";
	function display(){
		var color2 = "green";
		console.log('Color are ' + color +  ' and ' + color2);
	}
	display();
With above code,  variable color can be overridden unintentionally at any time which may affect the action of display function.

So how above code can be protected by using closure concept.

var getColor = function (){
	var color  = "red"; // this can be accessed by display function
	var display = function(){ // this is closure function
		var color2 = "green";
		console.log('Color are ' + color +  ' and ' + color2);
	}
	return display;
}
var colorObj = new getColor();
colorObj('yellow');

In the above example, the ‘display’ is closure function, it can access the “color” variable whenever this function will be invoked, but this variable can not be accessed from outside of getColor function, so it’s safe for being override.

What’s is the benefit of using Closure?

By using the Closure, we can make our code private, clean, and variables can not be modified by unintentionally.

Seperate enviroment with Closure

In below example, every time the getColor is invoked there will create the exclusive environment with closure and it’s related variables.  For example

var getColor = function (color){
	var color  = color; 
	var display = function(){ 
		var color2 = "green";
		console.log('Color are ' + color +  ' and ' + color2);
	}
	return display;
}

var colorObj1 = new getColor('red');
var colorObj2 = new getColor('blue');

colorObj1('yellow');
colorObj2('geeen'); 

new getColor('red'); and  new getColor('blue'); create the specific environment.  The environment has its own variable values red and blue with its own closure. Below figure shows the enviroment for above code



After invoking the closure function display,  it uses the value which was passed during the getColor() function called.

What happens when closure is used under the loop

function display(color){
	console.log('color is ' + color);
}
var getColor = function (){
	var onColors = [];
	var colors  = ['red', 'green', 'blue']; 
	for(var i=0; i < colors.length; i++){
		onColors[i] = function(){
			display(colors[i]);
		};
	}
	return  onColors;
}
var onColors = getColor();
onColors[0]();

In the above code, when we invoke the function onColors[0](); It suppose to display red color but It does not happen, because when the display() closure is invoked, the i has been reached to 3, so the output is “color is undefined”.

Under the loop, the getColor is not able to create the individual environment because of which the i’s value 3 is shared to all closures onColors[i].

So we need to make the individual environment for each closure and it’ related variables under the loop. Let's see how do we achieve this.

	function display(color){
		console.log('color is ' + color);
	}
	
	function eachColorEnvironment(color){
		return function (){
			display(color);
		}
	}
	
	var getColor = function (){
		var onColors = [];
		var colors  = ['red', 'green', 'blue']; 
		for(var i=0; i < colors.length; i++){
			onColors[i] = eachColorEnvironment(colors[i]);
		}
		return  onColors;
	}
	
	var onColors = new getColor();
	onColors[0]();

In this example, onColors[0](); renders the output “color is red”. Now getColor() is able to create separate environment with specific value and closure from eachColorEnvironment, as following,

First environment => Red and Closure


Second environment => Green and Closure


Third environment => Blue and Closure

Use “let” instead of  Closure.
	function display(color){
		console.log('color is ' + color);
	}
	
	var getColor = function (){
		var onColors = [];
		var colors  = ['red', 'green', 'blue']; 
		for(var i=0; i < colors.length; i++){
			let color = colors[i];
			onColors[i] = function (){
				display(color);
			}
		}
		return  onColors;
	}
	
	var onColors = new getColor();
	onColors[0]();
	
We can use the let keyword to handle this situation, this keyword can be used for block scope variable, so let color = “colors[i]” defines the private variable for its own closures.
let color = colors[i];
onColors[i] = function (){ display(color);}	

You can get the various examples about Closure.