Home > Programming > A brief introduction to closures

A brief introduction to closures

In this post, I’m going to attempt to explain what closures are and how to use them. Many modern (and some not-so-modern) programming languages contain support for closures, but for the purposes of this article I’m going to be using JavaScript. I’ve chosen JavaScript for a few reasons:

  • Ubiquity: If you have a web browser then you have a JavaScript interpreter
  • Simplicity: JavaScript is conceptually a fairly simple language (especially if you limit yourself to its Good Parts), compared to other dynamic scripting languages such as Python and Ruby
  • Familiarity: If you’ve used any of the C family of languages (e.g. C++, Java or C#) then JavaScript will look fairly familiar.

There may be some differences between languages with the mechanics, but deep down, closures are the same across all languages which allow them, so if you can understand the concept in JavaScript, you’ll understand it in any capable language.

Functional programming

Before I can get onto closures, I need to give a very brief introduction to functional programming.

Functional programming is all about functions (I doubt that comes as much of a surprise). In a language that surports functional programming, functions are generally first-class objects. That means they can be assigned to variables, stored in data structures, passed into functions and returned from functions.

In JavaScript, it’s important to distinguish between referencing a function and calling a function. To reference a function, just use the function name. To call a function, append parentheses (with optional arguments). Here’s an example:

function f() {
    alert('f called!');
}

f(); // calls f
var x = f; // f is a reference to the function, and now x is too
x(); // calls f (or x - they're the same thing)

It’s also possible to create anonymous functions in JavaScript (aka lambdas). If you want to create an anonymous function, leave out the name:

function () {
    alert('I have no name');
}

Another name for an anonymous function is a function literal. If you imagine it like a string literal you’ll see it’s an expression just like any other literal, and so it can be assigned to a variable:

var str = "string"; //string literal
var arr = [1, 2, 3]; //array literal
var obj = { 'JS': 1,
            'is': 2,
            'awesome': 3 }; //object literal
var f = function () {
    alert("I've been assigned to f");
}; //function literal

Note that there is very little difference between assigning an anonymous function to a variable called f and defining a function called f – the end result of both is a function that can be referred to by the name f, and can be called with f().

Another capability of functional languages is the ability to nest functions. It’s perfectly valid in JavaScript to define one function within another. Here’s another example:

function outer() {
    function inner() {
        alert('In ur function');
    }
    inner(); // we can call inner here as it is defined in outer's scope
}
inner(); // Error - but not here - inner is not defined in this scope

It’s this ability, coupled with the first-class nature of functions, that enables closures.

A real-life closure

A closure is a function with access to variables in its containing scope (the function “closes over” the variables). The thing that can be tricky to wrap your head round is that the inner function still has access to the outer function’s variables after the outer function has returned. Here’s an example:

function outer() {
    var counter = 0;
    function inner() {
        alert(counter);
        counter++;
    }
    return inner;
}

var x = outer(); // As we're calling outer here, x is a reference to inner 
x(); // alerts 0
x(); // alerts 1
x(); // alerts 2

In this code, outer is called once, and returns inner. x is a reference to inner. Because inner is a closure, it has access to outer‘s local variable, counter. Even though outer has returned, inner still has access to outer‘s variables. Be careful though – if outer were called again, we’d get a new version of inner. To continue the previous example:

var y = outer(); // Call outer again
y(); // alerts 0 - this is a different closure to the previous one.

The closure has access to any arguments in the containing scope as well:

function outer(x) {
    function inner() {
        alert(x);
    }
    return inner;
}

var func = outer(5);
func(); //alerts 5 - inner has access to the argument

A more advanced example

You should now know enough about the basics of closures to understand a more complex example. Here’s a way to give a JavaScript object private variables:

function CatMaker(name) {
    var age = 10;

    //construct an object on the fly with three methods.
    //All methods have access to age, but age cannot be
    //directly accessed outside of this function.
    return { 
        "sayHello": function () { //first method
            alert("Miaow");
        },
        "getAge": function (inCatYears) { //second method
            if (inCatYears) {
                return age * 7;
            }
            else {
                return age;
            }
        },
        "makeOlder": function () { //third method
            age++;
        }
    };
}

var mycat = CatMaker('Snuffles');
mycat.getAge(true); //returns 70
mycat.makeOlder();
mycat.getAge(true); //returns 77

The ONLY way to make changes to the private variable age is through the method makeOlder. All the methods share the same age variable, because they were all made in the same call of CatMaker. If we called CatMaker again to produce a new cat, it would have its own age variable.

The infamous lambda-in-a-loop problem

Consider the following example:

function attachListeners() {
    for (var i = 0; i < 10; i++) {
        $('#id-' + i).click(function () {
            alert("I am element number " + i);
        });
    }
}

It’s using jQuery. To understand this example you’ll need to know a tiny amount of how jQuery works. jQuery creates a global function called jQuery, aliased to $. The jQuery function takes (among other things) a CSS selector. It returns a jQuery object representing the HTML elements matching that selector. A click handler can be added by calling .click() on the returned object. .click() takes a function to be executed when the matched elements are clicked on. $('#myid').click(function () { alert('hello'); }); will show an alert when the HTML element with an id of ‘myid’ is clicked on.

The example selects 10 elements on the page, with the ids id-0, id-2 up to id-9. Each time round the loop, a new click handler is created. When you click on these elements, an alert box comes up. Some would think that each click handler has its own version of i but you know better. All the click handlers share the same i. Because of the way the for loop works, this value is one past the end of the loop, i.e. 10. So each element proudly announces that it is element number 10, which is clearly incorrect.

The problem here is that although a new closure is being produced each time round the loop, each closure shares the same environment, so i in each closure is the same i as in all the others.

Take a look at a working demonstration of the above code using jsFiddle. Have a play with it so you can get a feel for what’s going on.

The only way around this is to use another function:

function addOneListener(i) { //Each time i is bound to a different value
    $('#id-' + i).click(function () {
        alert("I am element number " + i);
    });
}

function addEventListeners() {
    for (var i = 0; i < 10; i++) {
        addOneListener(i); 
    }
}

Here’s the above as a fiddle. emehrkay in the comments has an alternative implementation of the above using raw DOM methods – it’s often useful to see different ways of achieving the same thing.

The key to understanding the new example is that every time addOneListener is called, a new closure is produced, and each of these closures has a different i. When you start using closures in JavaScript, this will bite you eventually, so beware. It’s such a common issue that bobince of HTML-parsing regex fame put it at number three in his list of common questions on Stack Overflow:

At number three it’s a new entry for “Why is my (Python, JavaScript, …) function getting the same value of the variable every time around the loop?”, by Clint Forloop and the Closures

  1. Bob
    November 23rd, 2010 at 23:24 | #1

    Your using jQuery so use it! Change the alert i to this.id

  2. November 23rd, 2010 at 23:45 | #2

    @Bob

    Thanks for the comment Bob. I think you’re missing the point slightly though; the example was to show what happens when you access a loop variable inside a closure.

  3. November 23rd, 2010 at 23:47 | #3

    Great article, found this to be a great read.

  4. emehrkay
    November 23rd, 2010 at 23:57 | #4

    Shouldn’t have used jQuery at all in that example, it only confuses things. Simple loop over an element collection with element.onClick = fn() would have been a better example.

    http://jsfiddle.net/3QphB/

  5. zorg
    November 24th, 2010 at 04:04 | #5

    “addOneListener is called, a new closure is produced, and each of these closures has a different i. “

    In every iteration in the attachListeners example, a new closure is also created, but they all end up capturing the same reference of i.

  6. November 24th, 2010 at 09:24 | #6

    @emehrkay Thanks, although I’m not convinced your example’s clearer. Anyone who understands CSS will understand the basics of selection in jQuery.

    Also, the reason I moved addOneListener outside of the loop was to make it clearer what’s going on – having that function inside the loop anonymously is fine, but to someone who’s learning all this for the first time might find that form a bit confusing.

    I’ve linked to your fiddle in the post anyway so readers can try out both ways and see which one makes more sense to them :)

  7. November 24th, 2010 at 09:31 | #7

    @zorg Yes, closures are being created in the first example, but they’re sharing the same lexical environment. The point is that they’re each created in a new environment in the second example.

    I’ve edited the post to clarify that closures are created in the first example.

  8. Vlad
    October 26th, 2011 at 05:07 | #8

    Great article, but a few things needed to be spelled out for newbies like me.

    First, you need to explain what “lexical environment” means. To give you some insight into the newbie mind, I had hastily assumed there is no difference semantically between:

    function g() {}         // g defined outside f and called inside f
    function f() { g(); }
    

    and

    function f() { function g() {}; ... } //g defined inside f
    

    I tended to think that g gets copied into the other function anyway. But based on your examples, I see that is precisely the issue. If a function is defined inside another function, it has access to the variables “above”, but if it’s defined separately, you need to pass the variables to it through parameters from within the outer function, which takes those values “outside” the scope of that function and “remembers” their values by way of separate variables defined inside the external function.

    Also, for a long while, I did not understand that the code of the inner function is executed when the main function is called (i.e. when a click event actually occurs, if it’s an event-handling function). I mistakenly interpreted each instance of the loop as separate and static, with the i value retrieved assigned at the time of the execution of each loop.

    For example, if I were to bind an event to some <a> element like so:

    a_element.attachEvent("click", function () { alert(i); })
    

    I assumed the value of i would be taken in the first loop as =0 and something like <a onclick="alert(0)"> would be inserted into the html right there and then. When the loop repeated, it would insert <a onclick="alert(1)"> etc. So I did not understand why the latest value of i could “intrude” on values of i that were already done with. But I see that the i defined in the loop is dynamic. Its value is retrieved at the time of the function call (or the event), which is after the loop has completed.

    The key seems to be that when a function is called and the i variable is accessed from the inner function, the same i is always accessed every time the inner function is called. What you need is to create another variable that can remember each i as it iterates through the loop.

    External function is one way. Alternatively, you can nest the functions and pass the “global i” to the inside function through a parameter, which achieves the same result:

    var func = function (i_holder) {
          return function() {
             alert(i_holder);
          }
    } (i);   // pass outer i as a parameter inside the function
    
    element.addEvent("onclick", func);
    
  9. Vlad
    October 26th, 2011 at 05:11 | #9

    @Vlad I didn’t know HTML would be parsed. Sorry. To correct the paragraph that has been turned in to a link:

    I assumed the value of i would be taken in the first loop as =0 and something like

    [a onclick="alert(0)"]

    would be inserted into the html right there and then. When the loop repeated, it would insert [a onclick="alert(1)"] etc. …

  10. October 26th, 2011 at 09:39 | #10

    @Vlad Hi Vlad, I’ve done my best to fix your HTML.

    I can’t reply to your entire comment right now, but to answer the first question about lexical environment:

    You’re confusing things a bit by talking about g being ‘copied’ into the other function. Code in f has access to g both times. The first time is because g is in f‘s parent scope. The second time is because g is in f‘s scope.

    What happens, when you call g() within f is this: In the first case, the interpreter will look for a definition of g within f. It won’t find it, so it looks in the parent scope, which is where g is defined. Otherwise, it would look to the next containing scope and so on until it reaches the global scope (the top level).

    In the second case, the interpreter will find the definition of g within f.

    The important thing is though, that g is not ‘copied’ into f. There is only the one g, and the interpreter searches up the scope chain until it is found.


    It seems that you have some fundamental misconceptions about the way JavaScript works – I’d recommend you read Eloquent JavaScript. Good luck!

  11. Viko
    July 1st, 2012 at 17:06 | #11

    I think that this could be another approach if you don’t wan’t to create an external function: function attachListeners() { for (var i = 0; i < 10; i++) { (function(j) { $('#id-' + j).click(function () { alert("I am element number " + j); }); }(i)); } }

    But this is less readable… :P

  12. Cobus
    September 19th, 2012 at 12:09 | #12

    This is the first post I’ve read that clearly illustrates what a closure is to someone who had no idea. Just explain what is going on with the return statement that returns 3 comma separated functions? Does this mean that myCat is a reference to all 3 functions at the same time?

    Thanks for a great post!

  13. September 20th, 2012 at 00:49 | #13

    @Cobus Cool, thanks! Yeah, CatMaker returns an object literal:

    return {
      "sayHello": function () { ... },
      "getAge": function (inCatYears) { ... },
      "makeOlder": function () { ... }
    };
    

    so it’s creating a new object with three methods, which all have access to the closure-scoped variable, age. Hope that makes sense!

  14. Cobus
    September 24th, 2012 at 18:55 | #14

    Thanks I understand it better now. @Skilldrick

  15. Andy
    September 17th, 2014 at 11:28 | #15

    Easily the clearest explanation of the concept I have found so far, and I have been searching quite intensively! Thank you for producing this article.

  1. November 23rd, 2010 at 02:55 | #1
  2. November 23rd, 2010 at 13:24 | #2
  3. April 26th, 2011 at 11:25 | #3
  4. January 22nd, 2013 at 16:28 | #4

Comments parsed as Markdown.