February
14th, 2008
Closures - Demystifying Javascript’s secret weapon
Per Wikipedia, a closure is defined as “a function that is evaluated in an environment containing one or more bound variables“.
What’s a closure look like?
function MyFunction()
{
var LocalVariable = 'This variable is only accessible from inside this function.';
var myClosure = function(){ alert(LocalVariable); }
return myClosure;
}
The closure in the code above is var myClosure = function(){ alert(LocalVariable); }. That’s great but what’s it mean and why should you care? If you’re comfortable hacking Javascript libraries or writing your own then understanding closures is a key concept to grasp. The best way to really understand something is to play with it, so I’m not going to go into great detail with this entry. The goal of this article is to give you enough information to start playing with them.
Anonymous functions
Typically you define a function using the syntax function MyFunctionName(). Javascript lets you define functions anonymously which means you can omit the name and still define a function. This is great if you want to do something like pass a function as an argument without formally naming it or save the function to a variable. We will be doing the latter.
When function calls disappear
Once you call a function it generally executes and disappears taking with it anything which was passed into it or calculated inside of it. Let’s say that you have a page which has a form field which asks for the visitor’s name when the page loads using Javascript’s prompt function. Let’s say you also want to use Javascript’s wonderful alert function to give the user a personalized notification of the time every 10 seconds. Now you’d like to implement that without storing a global variable because that really mucks things up.
Here’s how you could do that using a closure.
function annoyUser()
{
var name = prompt("What's your name?");
var myClosure = function()
{
var d = new Date();
alert(name + " the time is " + d.toUTCString());
}
setTimeOut(myClosure, 10000);
}
annoyUser();
How does this work?
This works because when you create the myClosure variable as an anonymous function a closure is created. That means any variables available to the function you’re in, in this case annoyUser. This includes the name variable you collected from the visitor. The beauty is that this closure persists the name of the visitor so that you can reference it again using the myClosure variable. Which is specifically what we are doing…calling myClosure every 10 seconds. Generally what you might do is return myClosure and use it later or pass it into other functions.
What’s the point?
You might be thinking that you can do this by simply declaring a global variable like this: var name = prompt(”What’s your name?”). You could then access that global variable from anywhere, including functions. That’s yucky. If you don’t know why…keep writing Javascript and come back here in a few months :).
Leveraging closures
Prompts and alerts are hardly the point of this exercise. Once you get comfortable with closures you’ll begin to look at solving problems with Javascript differently. Hopefully it introduces a paradigm shift into your Javascripting.
