Search

Closures in JavaScript

What is a closure

A closure is an inner function that has access to the outer function’s variables in addition to it's own variables and global variables. The inner function has access not only to the outer function’s variables, but also to the outer function’s parameters. You create a closure by adding a function inside another function.

// Example 1
function addNumbers(firstNumber, secondNumber) 
{
    var returnValue = "Result is : ";
    // This inner function has access to the outer function's variables & parameters
    function add() 
    {
        return returnValue + (firstNumber + secondNumber);
    }
    return add();
}

var result = addNumbers(10, 20);
document.write(result); //30

Output : Result is : 30

The following code Returns the inner function expression

//Example 2 - with closure (The following code Returns the inner function expression)
function addNumbers(firstNumber, secondNumber) 
{
    var returnValue = "Result is : ";
    function add() 
    {
        return returnValue + (firstNumber + secondNumber);
    }
    // We removed the parentheses. This will return the inner function expression without executing it.
    return add;
}

// addFunc will contain add() function (inner function) expression.
var addFunc = addNumbers(10, 20);

// call the addFunc() function and store the return value in result variable
var result = addFunc(); //result = 30
document.write(result);

Returning and executing the inner function

//Example 3 - (Returning and executing the inner function)
function addNumbers(firstNumber, secondNumber) 
{
    var returnValue = "Result is : ";
    function add() 
    {
        return returnValue + (firstNumber + secondNumber);
    }
    // We removed the parentheses. This will return the inner function add() expression without executing it.
    return add;
}

// This returns add() function (inner function) definition and executes it. Notice the additonal parentheses.
var result = addNumbers(10, 20)();
document.write(result);


//Example 4 - (with click counter)
var incrementClickCount = (function () 
    {
        var clickCount = 0;
        return function () 
        {
            return ++clickCount;
        }
    })();

alert(incrementClickCount);

In the Example 4 above, in the alert function we are calling the variable incrementClickCount without parentheses. At this point, when you invoke, you get the inner anonymous function expression in the alert. The outer self-invoking anonymous function run only once and sets clickCount variable to 0, and returns the inner function expression.

Whereas inner function has access to clickCount variable. Now every time we click the button, the inner function increments the clickCount variable. The important point to keep in mind is that no other script on the page has access to clickCount variable. The only way to change the clickCount variable is thru incrementClickCount function.


Functional Inheritance in javascript

Functional Inheritance

This example shows how functional inheritance can be used in javascript without #prototype or #new and take advantage of Javascript's ability with argument & objects

//define an object
var baseObject = function(publicName,privateVar){
    
    var baseContext = { // object literal
        Name:publicName,
        getInfo : function(){
            return this.Name + " you are " + privateVar ; //Any local variable remain private
        }
    };
    return baseContext;
};

// inherit form baseObject
var person = function(name,occupation){
    var that = baseObject(name,occupation); //inherit from base
    that.action = function(){ //extend base with a method
        return "You know nothing " + that.Name ;
    }
    return that;
};

//calls
debugger;
console.clear();

// create instance of the extended class
var man = person("John Snow","Stark"); 
var person1 =  (man.getInfo());
var person1does= (man.action());
man.Name = "Eddard"; // Change the name of person
man.privateVar = "Lord of wintefell"; //will not change as it's private
var person2 = (man.getInfo());
var person2does = (man.action());

//print
console.log(person1);
console.log(person1does);
console.log(person2);
console.log(person2does);