JavaScript closures

I like JavaScript! There, I said it!

I work in a JavaScript hostile environment where people want to do everything in pure Java, which is why I spend most of my time trying to get JSF and a Portal server to play together nicely (sad story!). But! Deep down I long for a simpler life, a life consisting of HTML, CSS and pure JavaScript and nothing else (well maybe a bit of PHP on the server).

So why do I like JavaScript? I like it because it’s so dynamic. Need a method on an object? Just add it when you need it. You can bend the rules and pretty much do as you please. More than once has JavaScript saved our arse when normal server side programming has failed. And then there’s the more “hard to grasp when you’re used to Java” features. Things like that a function can return a function, callback functions, scope of variables and closures.

Especially closures I’ve had quite a few attempts at trying to understand. I’ve been attending a JavaScript course recently which was very interesting and fun. Of course we were discussing closures and this time I think it finally clicked. Therefore, to remember, I’ll write this post, so that I can re-read it in six months when I’ve forgotten about closures again.

Definition of a closure

Here’s my definition of a closure: The fact that an inner function can get access to outer variables is called a closure. The inner function “closes around” the outer variables and have access to them, even after the “environment” where the outer variables were defined is dead (removed from the execution context/scope chain).

An Example

Here’s a simple example:

var closureOne = function(){
       var outerVarOne = "hey there, I'm outerVarOne. You might remember me from such classics as: closureOne";
       var returnFunction = function(){
          console.log("This is written in the returned function from closureOne, and here's outerVarOne: " + outerVarOne);
	}
	return returnFunction();
}

The variable closureOne is a function. In this function we define a variable called outerVarOne. This variable is now visible inside the closureOne function. Here’s where things start to get interesting, we now define an inner function called returnFunction in our closureOne function. The function in this case is quite simple. All it does is write a message which includes outerVarOne. In other words: This inner function has access to outerVarOne.
Finally we return the result of executing returnFunction as the result of closureOne.
Eh! What’s so special about that? Nothing yet, but now the scene has been set. I can now call my closureOne function like so:

console.log('before closureOne');
closureOne();
console.log('after closureOne');

And see the following in my console:

before closureOne
This is written in the returned function from closureOne, and here's outerVarOne: hey there, I'm outerVarOne. You might remember me from such classics as: closureOne
after closureOne

What’ll happen when I call my closureOne function is, that it will add itself to the scope chain…including it’s outer environment! The trick is, that even though I’m calling closureOne, that’s not really the function that’s being called. The function being executed is the outcome of the inner returnFunction that we defined. And since returnFunction needed access to outerVarOne, it has created a closure around it, meaning that returnFunction has access to outerVarOne, even though this variable is no longer accessible to the rest of the world, as it was removed from the scope chain when closureOne was originally executed!
Mind blowing eh? And just to prove the point, let’s see what happens if I were to try to read the value of outerVarOne from outside my closure:

console.log('before closureOne');
console.log(closureOne.outerVarOne);
closureOne();
console.log(closureOne.outerVarOne);
console.log('after closureOne');

So, here I’m trying to get access to outerVarOne twice, before and after executing closureOne(); and the result:

before closureOne
undefined
This is written in the returned function from closureOne, and here's outerVarOne: hey there, I'm outerVarOne. You might remember me from such classics as: closureOne
undefined
after closureOne

See, I cannot get access to the outerVarOne as it is dead to the outer world because the closureOne function has already been executed and removed from the scope chain, only in my closure can I get access to it.

Another Example

Here’s another example, this time we’re using the module pattern, meaning that we’re executing the function straight away:

var closureTwo = (function(){
	var innerVarTwo = "hey there, I'm innerVarTwo. You might remember me from such classics as: closureTwo";
	return function(){
		console.log("This is written in the returned function from closureTwo, and here's innerVarTwo: " + innerVarTwo);
	};
})();

Apart from that, nothing much is different from the first example. The advantage of the module pattern is that you can ensure privacy due to the fact that your function is executed right after it is defined. This also means that it is popped of the execution chain straight away, but!…Your closure will still have access to any private variables that it needs, when it is run.

A Final Example

Here’s a final example. This time we’re sending a parameter to the called function:

var closureThree = function(aParam){
	var innerVarThree = "hey there, I'm innerVarThree. You might remember me from such classics as: closureThree";
	return function(aParam){
		console.log("This is written in the returned function from closureTwo, and here's innerVarThree: " + innerVarThree + " and here's aParam " + aParam);
	}(aParam);
}

The syntax for doing so is a bit quirky I think. First off the parameter is defined in the returned (anonymous) function, fair enough. Now, since it is just a pass through, we need to define it in our declaration of closureThree, makes sense too. Finally, as we’re calling this function straight away, we need to attach a parameter, otherwise the aParam would be ‘undefined’. Therefore aParam is added as a parameter to the (); part at the end of the function.

To actually use this function you need to call it like so:

console.log('before closureThree');
closureThree('Peter');
console.log('after closureThree');

I guess that’s all there is to it.

That’s All Folks

So there you go, that’s how closures work. Once you get it into your head it’s easy to understand actually, but so far it has taken me three or four attempts to understand it, and who knows, maybe I’ll forget it again in another six months, but then I have this blog to return to, and hopefully it’ll help me remember closures.

Or I could just start coding some JavaScript…any suggestions?

Leave a Reply

Your email address will not be published. Required fields are marked *