Introduction
Definition - A closure is a function together with a referencing environment for the non-local variables of that function. << refer to link http://en.wikipedia.org/wiki/Closure_(programming) >>
In JavaScript, using simple terms, if we create a function inside another function, we are creating a closure.
In most common languages, after a function returns, all the local
variables are no longer accessible because the stack-frame is destroyed. Keeping this in mind a closure can be considered as a stack-frame which is not deallocated when the
function returns.
Why use Closure
I have many asking me why closures are required. I will try to explain.
The scenario where I came across closures was while using Tabular Controls, File Objects etc. With Closures I could store the page indexes, row counts etc that I could re use for other client functions. With FSO i could have file paths , counts etc saved for later use. Its not only for complex client controls. Think of scenarios where your page has many controls and you are performing client side validations. Each time you acces a control by
document.getElementById("controlname")
the whole page control tree is being searched. This can be avoided by using closures and saving the controls just once. Re-usability is a key advantage of closures. Hope I have convinced few to atleast get to know Closures.
Using the code
Take a look at the function below:
function sayHello(name) {
var text = 'Hello ' + name;
var sayAlert = function() { alert(text); }
return sayAlert;
}
Now we call the function in the following way:
var say2 = sayHello("Sachin");
say2();
The function sayHello()
returns a pointer to the function sayAlert()
.
Here when you declare a function within another function, then the local variables can remain accessible after returning from the function you called. This is demonstrated above; we call the function say2()
after we have returned from sayHello()
. Notice that the code that we call references the variable text
, which was a local variable of the function sayHello()
.
Consider the function below:
function setupSomeGlobals() {
var num = 666;
gAlertNumber = function() { alert(num); }
gIncreaseNumber = function() { num++; }
gSetNumber = function(x) { num = x; }
}
The three functions gAlertNumber()
, gIncreaseNumber()
, and gSetNumber(x)
have shared access to the same closure - the local variables of setupSomeGlobals()
when the three functions were defined.
This can be checked by calling the functions one after the other.
Try the below sequence:
setupSomeGlobals()
gAlertNumber ()
gIncreaseNumber()
gAlertNumber ()
gSetNumber (600)
gAlertNumber ()
If we call setupSomeGlobals()
again, then a new closure (stack-frame!) is created. The old gAlertNumber
, gIncreaseNumber
, gSetNumber
variables are overwritten with new functions that have the new closure.
Summary
- A closure in JavaScript is like keeping a copy of all the local variables, just as they were when a function exited.
- It is probably best to think that a closure is always created just on the entry to a function, and the local variables are added to that closure.
- A new set of local variables is kept every time a function with a closure is called (given that the function contains a function declaration inside it, and a reference to that inside function is either returned or an external reference is kept for it in some way).