Tuesday 16 August 2011

How do JavaScript Closurers Work

Closure

A closure takes place when a function creates an environment that binds local variables to it in such a way that they are kept alive after that function has returned. A closure is a special kind of object that combines two things:
  • ·         A function
  • ·         A local variable that is in scope at the time that the closure was created.
In other words a closure is the local variables for a function kept alive after the function has returned or a closure is a stack-frame which is not deallocated when the function returns. 

For instance:

function  myFullName(){
                var firstname = “Tendai”;
                function getName(){     
                                alert(firstname);
}
getName();
}
myFullName();

The function myFullName() creates a local variable called firstname, and then defines a function called getName(). Function getName() is an inner function – it is defined inside myFullName, and is only available within the body of that function. As you can see, the function getName() has no local variables of its own, but reuses the name variable declared in the outer function, myFullName().

If you run the code, you are going to notice that it is going to show ‘Tendai’. This is an example of functional scoping, whereby the scope variable is defined by its location within the source code, and the nested functions have access to variables declared in their outer scope.

Let us look at another example:

function myFullName(){
                var firstname =”Tendai”;
                function getName(){
                                alert(firstname);
}

return getName;
}
var myName = myFullName();
myName();

This code will have the same result as before. The difference here is that, getName() is an inner function that was returned from the outer function before being executed. Under normal circumstances the local variables within a function only exist for the duration of that function’s execution. Once myFullName() has finished executing, it is reasonable to expect that the firstname variable will no longer be necessary, which is not the case here. 

The reason behind this is that myName has become a closure. Remember that a closure combines two things:
myName is a closure that incorporates both the getName function and  the local variable, string “Tendai”,  that was in scope at the time the closure was created.

Now the complete example:

function myFullName(firstname){
                return function(surname){
                                return firstname + surname;
};
}
var myFullNameTendai =myFullName(‘Tendai’);
var myFullNamePeter =myFullName(‘Peter’);
print(myFullNameTendai (‘Bepete’)); // Tendai Bepete
print(myFullNamePeter (‘Jacobs’));// Peter Jacobs

Here, the function myFullName(firstname) takes a single argument firstname and returns a new function. The function it returns takes a single argument surname, and returns a concatenation of firstname and surname.

Both myFullNameTendai and myFullNamePeter are closures. They share the same function body definition, but store different environments. In myFullNameTendai’s environment, firstname is Tendai and that in myFullNamePeter it is Peter.
Hope after reading this you had a better understanding on what closurers are and how they work. For further reading you can read this article.