There are many things that web developers should know about JavaScript, but the most basic of things are anonymous functions and closure. Both are very powerful tools for anyone working with JavaScript.

So what's so great about them you ask? Well, I think that's best explained using some examples.

Let's say we want to implement a function that will take an integer representing a month, and return it's name as a string.
e.g. 1 -> 'January', 2 -->  'February', 9 --> 'September'

We'll start out with a naive implementation, but perhaps one that first comes to mind.

function monthName(i) {
  var months = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'
  ];

  return months[i-1];
}

Simple right? But there's something wrong with this function. Take a look at the array declaration, it's inside the function! That means everytime you call the monthsName function, it'll create an array. This not only slows down your function, but it uses an unnecessary amount of memory.

Our first improvement then, would be to move the array to the outside of the function.

var months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
];

function monthName(i) {
  return months[i-1];
}

Great, now we only create array once! But wait, there's another problem. We've just moved the months array into the global namespace. This is bad because we might be overwriting a previously declared variable also named months. Similarly, someone later on might overwrite our months array. D'oh!

Fortunately, there is a way around this. And this is where anonymous functions and closure come in. Let me show you the solution first.

var monthName = function() {
  var months = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'
  ];

  return function(i) {
    return months[i-1];
  };
}();

So how does this work?

First, you'll notice the block of code inside the outter function is similar to our second solution, except that the function name has been dropped, and it is now the return value of the outter function. The outter function is executed immediately,  and is assigned to the variable monthName. Thus monthsName is really the inner function. Sort of.

Here is where closure comes in. The inner function refers to the months array declared outside of it, but because of closure, that array is bound to the function. So when we call the function monthName we are really calling the returned result of an anonymous function (which itself is an anonymous function). And this returned function has the months array bound to it.

Here's another example using anonymous functions and closure to implement Partial Application in Javascript.

Function.prototype.papply= function() {
  var fixed = Array.prototype.slice.call(arguments),
    fn = this;
  return function() {
    return fn.apply(this, fixed.concat(Array.prototype.slice.call(arguments)));
  };
}    

Of course, you can probably achieve everything I've shown here without anonymous functions or closure, but why make it hard for yourself? Learn these tools, use them to your advantage!



blog comments powered by Disqus