Friday, October 14, 2016

Understanding Closures and its uses In JavaScript


Understanding Closures in Details and  using it practically In JavaScript 


Basic understanding:

A closure is an inner function that has access to outer function variables.

Example:

function foo(){
var name = "furious";
function zoo(){
return "your name is "+ name;
}
return zoo();
}
foo();

As you can see the inner zoo function can access outer foo function variable name.

Practical Implementation/Use:

  • Creating a variable that retains its value in multiple executions like static variables in Java.
    Example: Creating a counter that is incremented on each page view.
    Lets take the below function and check its output.
var counter = function(){
var count = 0;
++count;
console.log(count);
}
}
counter();
counter();
counter();

Output:
1
1
1


As you can see each time the output is 1 because the counter value is always initialized by 0 when the program is executed multiple times.

Now Lets take below example:
var counter = function(){
var count = 0;
return function(){
++count;
console.log(count);
}
}

var increment_pageviews = counter();

increment_pageviews();
increment_pageviews();
increment_pageviews();

Output : 

1
2
3

Run increment_pageviews() multiple times and you can see that the value is  incremented each time.So in above example the value of count is retained.


  • Creating a private variable that cannot be accessed outside the function and its value can only be changed by internal functions like private data members in Java.

    Example: Expanding above example of counters :
  • var counter = function(){
    var count =0;
    return {
    increment : function(){
    console.log (++count);
    return count;
    } ,
    decrement: function(){
    console.log(--count);
    return count ;
    },
    reset : function(){
    count =0;
    console.log(count);
    return count;
    }
    }
    }

    var pageviews = counter();
    pageviews.increment();
    pageviews.increment();
    pageviews.increment();
    pageviews.decrement();
    pageviews.reset();

    output :

    1
    2
    3
    2
    0

    As we can see here that count is a private variable  and can only be manipulated by 3 exposed public function increment(), decrement() & reset() only.

    Deeper Dive into Closures

    Let us take the below example: 
    function add(int x){
    var count = 0 ;
    return function(){
    count += x;
    console.log(count);
    return count;
    }
    }

    var sum = add(3);
    sum();
    sum();
    sum();

    Output:
    3
    6
    9

    Now If the concept of closures was not present , then the above function would have given below output :
    3
    3
    3

    Lets see how closures helps to retains the value of the count variable.
    Now, As we know each function in the javascript has his own heap space where it keeps its variables and reference of the inner functions.
    Also when the function execution is completed & there is no reference for that function i.e there is no reference available for that function the garbage collector clears the heap and remoes all the items in that memory.

    In case of above example
    the first heap area is created for the file, which stores the empty variable sum and reference to function add().

    When add(3) is executed , Another heap area is created  which stores the variable count & reference for inner anonymous add function.

    The reference of this inner anonymous function is also stored in the sum variable of the parent heap.
    Now after the execution of the add function is completed , ideally the count variable must have destroyed. But since there is one more variable sum in the main/parent heap which is having the reference of the inner anonymous function , the heap of add function is not cleaned by garbage collector.So whenever the sum function is called the value stored in the parent heap is incremented & returned. This is the reason why the value of the count is retained in every call .

    Please refer below video for more detailed study of this feature called closure: