Closures are inner functions that can access outer function's parameters. It is a combination of function and the environment it has created. A closure is a nested function which can access variables of its immediate lexical scope. Closures have variables of 3 scopes: its own variables, it’s access to outer function variables and global variables.

Nested functions can continue to access variables from outer function, even after outer function finished execution. The browser keeps the lexical environment and it’s variables in memory until there is an inner function referencing it. When the variables in outer function change, inner function has the reference of variable and accesses the latest value. Functions can be nested in more than one level.

When a function has another function inside it, an external reference is kept for the inner function or its reference is returned. Closures cannot access the this keyword and argument binding of external function unless it is stored in a variable.

NOTE: Closures are extensively used in Node.js and jQuery.

Example with JavaScript closure

Working with closures on arrays can be deceiving when we do not understand the references and scopes in them. Consider an array of functions called funcs[] in example below. They are all defined within the dispInt() as anonymous functions. The aim of the function was to display numbers from 0-4. When funcs[] is returned, ‘i’ value is 5. Hence all the funcs[] return 5.

Example with JavaScript closures and arrays

<script>
    function dispInt(){
        var funcs = [];        
        for(var i=0; i< 5; i++){
            funcs[i] = function(){    return i; };            
        }            
        return funcs;
    }        
    var funcs = dispInt();
    for(var j=0; j<5; j++){
        document.write(funcs[j]()); // 5 5 5 5 5 
     }
    </script>

The above example shows unexpected result because, closures access the reference of the variable and do not make private copies of them. The scope chain associated with the anonymous function is live and stores the value of 5 while exiting the loop. Hence to get the desired output in above function following modification is necessary:

<script>
    function dispInt(){
        var funcs = [];            
        for(var i=0;i<5; i++){
            funcs[i] = arrFunc(i);                
        }
        return funcs;
//The index is returned each time and stored in function array.
function arrFunc(j){                    
        return  function(){
                return j; 
   };                            
        }

var funcs = dispInt();
for(var i=0; i<5; i++)
    document.write(funcs[i]()); //0 1 2 3 4
</script>

Memory leaks in a closure

Closures are huge cause of memory leaks in JavaScript when not handled right, because inner functions hold reference to outer function variables even after outer function terminates. Consider the example below:

Example of memory leaks by JavaScript closure

var logo = null;
var newLogo = function(){
    var firstLogo =  logo;
    logo = {
          logoDesign : new Array(10000).join(“*$%^*”);
        someMethod : function(){
            //code which might use logo
}
}
// Avoids memory leaks as there is no big value linked to it.
firstLogo = null; 
}
setInterval(newLogo, 1000);

If someMethod is indirectly using firstLogo for some evaluation in eval() or has the firstLogo in it’s lexical scoping, the firstLogo is prevented from garbage collecting even after the function execution ended. Refreshing browser often, will lead to reduced performance because of large values stored in firstLogo leading to a memory leak. Hence making the variables which comes in lexical scoping as null at the end of function, prevents accumulation of large values and memory leak (object de-referencing).

 

›› go to examples ››