Closures
in
Javascript



Closures are very unique and an integral part of Javascript. JS, Jquery , node.js etc programmers come across closures every now and then. At first instance , closures might look complex and intimidating but once you understand the underlying concepts involved , you will find them very easy.

What is a Closure ?

In most simple words, A closure is a function inside a function i.e. an inner function which can access the variables and scope chain of the outer function. Scope chains of closures

  • Closures have access to global variables
  • Closures have access to its parent/outer functions variables
  • Closures have access to its own scope

The inner function can also access the parameters of the outer functions but it can not call its argument objects however it can call the parameters directly. Consider the following simple examples of closures :
		        
function Add (x, y) {
	var data = "The sum is";
	//This inner function has access to the outer function's variables, including the parameter
	function sum () {       
		return data + x + y ;   
	}

	return sum();
}

Add (10, 12); // The sum is 22
				
	            

This is a very basic example of closures but it is not a practical application of them.

Underlying concept behind closures !

Consider the example given below : In this example we are creating a local variable value in the outer function demo(). After that we are creating a inner function named demoInner(). Although demoInner() does not have any of its own variable but can access the variable of its parent function. Hence , demoInner() is using the variable value declared in the demo() function.


		        
// function demo 
function demo() {
  var value = 'Nodejsera'; 		//It is a Local Variable
  function demoInner() { 	// inner function or Closure
    console.log(value); 		// use variable declared in the parent function    
  }
  demoInner();    
}
demo();
                
	            

After running the code we observe that it executed successfully as expected i.e. the inner function demoInner()successfully log the value of the variable value which is declared in the outer function. this is an example of lexical scoping. Lexical scoping uses the storage location of the variable within the source code in order to determine the availability of the variable. Nested functions have access to variables declared in their outer scope.
Now consider another example given below :


		        
//A basic closure example
function Nparent() {
  var value = 'Nodejsera';		//A local Variable declared 
  function Nchild() {			// closure
    console.log(value');		// use variable declared in the parent function    
  }
  return Nchild();
}

var Nfunc = Nparent();
Nfunc();
                
	            

It will give you the same result as the previous example. the only difference is that the inner function is returned from the outer function before the outer function is being executed. Normally the local variables inside a function only exists for the duration of that function's execution. Once the execution is done , the variables would no longer remains accessible but definately this is not the case here. The reason is the existence of closures in Javascript.A closure is simply a combine of a function and the lexical environment.
So this environment consists of all the local variable that were in scope when the closure was created.

Features of closures
  • Closures have access to the outer functions variables even after the outer function is already executed and returned the execution control.
    Consider the following code :


    		        
    function studentName (name) {
        var stu = "Name of the student is ";
       
       function branch (batch) {
            return stu + name + " and his branch is" + batch;
        }
        return branch;
    }
    
    var clg = studentName ("Amit");	 // At this Point, the studentName outer function has returned.
    
    clg ("Computers"); // Name of the student is Amit and his branch is Computers
                    
    	            

    In the above example the inner function branch() has access to the variables and parameters of the outer function studentname(). The closure branch() is called after the outer functions execution is done and it has returned but still the closure has access to the variables and parameters of the outer function.

  • Closures does not store the value of the outer function instead they stores their references.
    		        
    function A () {
        var value  = 1 ;
       
        return {
            Print : function ()  {
               
                // It will return the current value of value, even after the newValue function changes it
              return A;
            },
            change : function (newValue)  {
                // this function can change the outer function's variable anytime
                A = newValue;
            }
        }
    
    }
    
    var data = A (); // At this juncture, the A outer function has returned.
    data.print(); // 1
    data.change(5); // Changes the outer function's variable
    data.print(); // 5  It returns the updated A variable
                    
    	            

    In the above example we are returning an object with some inner functions and all the the inner function have access to the variables of the outer function.
Performance considerations in Closures

It is not recommended to create functions within functions if closures are unncecessary and not needed for that task because it will affect script performance negatively both in terms of processing speed and memory consumption.

Summary
In this article we learned the following :
  1. Intoduction to closures
  2. What is a closure ?
  3. Underlying concept behind closures !
  4. Features of closures
  5. Performance considerations in closures