Home > Programming > Closures explained with JavaScript

Closures explained with JavaScript

Last year I wrote A brief introduction to closures which was meant to help people understand exactly what a closure is and how it works. I’m going to attempt that again, but from a different angle. I think with these kinds of concept, you just need to read as many alternative explanations as you can in order to get a well rounded view.

First-class functions

As I explained in Why JavaScript is AWESOME, one of the most powerful parts of JavaScript is its first-class functions. So, what does “first-class” mean in a programming language? To quote wikipedia, something is first-class if it:

  • can be stored in variables and data structures
  • can be passed as a parameter to a subroutine
  • can be returned as the result of a subroutine
  • can be constructed at runtime
  • has intrinsic identity (independent of any given name)

So, functions in JavaScript are just like objects. In fact, in JavaScript functions are objects.

The ability to nest functions gives us closures. Which is what I’m going to talk about next…

Nested functions

Here’s a little toy example of nested functions:

The important thing to note here is that there is only one f defined. Each time f is called, a new function g is created, local to that execution of f. When that function g is returned, we can assign its value to a globally defined variable. So, we call f and assign the result to g5, then we call f again and assign the result to g1. g1 and g5 are two different functions. They happen to share the same code, but they were executed in different environments, with different free variables. (As an aside, we don’t need to use a function definition to define g and then return it. Instead, we can use a function expression which allows us to create a function without naming it. These are called ‘anonymous functions’ or lambdas. Here’s a version of the above with g converted to an anonymous function.)

Free variables and scope

A variable is free in any particular scope if it is defined within an enclosing scope. To make that more concrete, in the scope of g, the variable x is free, because it is defined within the scope of f. Any global variables are free within the scopes of f and g.

What do I mean by scope? A scope is an area of code where a variable may be defined, without the enclosing scope knowing about it. JavaScript has ‘function scope’, so each function has its own scope. So, any variable defined within f is invisible outside of f. Scopes can be nested, so in the above example, g has its own scope which is contained within the scope of f, which is contained within the global scope. Whenever a variable is accessed, the JavaScript interpreter first looks within the current scope. If the variable is not found to be defined within the current scope, the interpreter checks the enclosing scope, then the enclosing scope of the enclosing scope, all the way up to the global scope. If the variable is not found, a ReferenceError is thrown.

Closures are functions that retain a reference to their free variables

And this is the meat of the matter. Let’s look at a simplified version of the above example first:

It’s no surprise that when you call f with the argument 5, when g is called it has access to that argument. What’s a bit more surprising is that if you return g from the argument, the returned function still has access to the argument 5 (as shown in the original example). The bit that can be a bit mind-blowing (and I think generally the reason that people have such trouble understanding closures) is that the returned g actually is remembering the variable x that was defined when f was called. That might not make much sense, so here’s another example:

When person is called, the argument name is bound to the value passed. So, the first time person is called, name is bound to ‘Dave’, and the second time, it’s bound to ‘Mary’. person defines two internal functions, get and set. The first time these functions are defined, they have a free variable name which is bound to ‘Dave’. These two functions are returned in an array, which is unpacked on the outside to get two functions getDave and setDave. (If you want to return more than one value from a function, you can either return an object or an array. Using an array here is more verbose, but I didn’t want to confuse the issue by including objects as well. Here’s a version of the above using an object instead, if that makes more sense to you.)

And this is the magic bit. getDave and setDave both remember the same variable name, which was bound to ‘Dave’ originally. When setDave is called, that variable is set to ‘Bob’. Now when getDave is called, it returns ‘Bob’ (Dave never liked the name ‘Dave’ anyway). So getDave and setDave are two functions that remember the same variable. This is what I mean when I say “Closures are functions that retain a reference to their free variables”. getDave and setDave both remember the free variable name. Even though person has now returned, the variable name lives on, because it is referenced by getDave and setDave.

The variable name was bound to ‘Dave’ when person was called the first time. When person is called a second time, a new version of name comes into existence, as well as new versions of get and set. So the functions getMary and setMary are completely different to the functions getDave and setDave. They execute identical code, but in two different environments, with different free variables.

Summary

In summary, a closure is a function called in one context that remembers variables defined in another context – the context in which it was defined. Multiple closures defined within the same context remember that same context, so changes they make are shared between them. Every time a function is called that creates closures, a new, shared context is created for the new closures.

The best way to learn is to play, so I’d recommend editing the fiddles above (by clicking on the + at the top right) and having a fiddle. Enjoy!


Addendum: Lasse Reichstein had some useful comments on this post on the JSMentors mailing list – read them here. The important thing to realise is that a closure actually remembers its environment rather than its free variables, so if you define a new variable in the environment of the closure after the closure’s definition, it will be accessible inside the closure.

  1. April 23rd, 2011 at 07:27 | #1

    A closure is a reference to a function that remembers the scope in which the function was declared. That’s why, in the following modified example (the really interesting stuff is occurring in the last anonymous function), the another_name variable value is retained inside person() even though the scope calling person() has redefined another_name.

    var another_name = 'bill';
    
    function person(name) {
        console.log(another_name);
        function get() {
            return name;
        }
        get.prototype.myprop = 'hello world';
        function set(newName) {
            name = newName;
        }
        return [get, set];
    }
    
    (function() {
        var getSetDave = person('Dave');  // output: 'bill'
        var getDave = getSetDave[0];
        var setDave = getSetDave[1];
        console.log(getDave()); // output: 'Dave'
        setDave('bob');
        console.log(getDave()); // output: 'bob'
    })();
    
    (function(another_name) {
        console.log(another_name); // output: 'lee'
        console.log((person('sarah')[0])());  // output: 'bill', 'sarah'
    })('lee');
    
  2. April 24th, 2011 at 17:11 | #2

    @Lee Powers

    As I see it (please correct me if I’m wrong), it is not just the value of another_name inside person(), but full access to the variable that is retained. Person closes over the variable another_name declared in the global object scope, and it is subjected to changes in that variable(see example below).

    The second use of another_name in the anonymous function is not really redefining the one in the global object. As you say, it is in a different scope, and the variable (although it has the same name) is a different one.

    If you continue that code with:

    another_name='jos';
    (function(another_name) {
        console.log(another_name); // output: 'lee'
        console.log((person('sarah')[0])());  // output: 'jos', 'sarah'
    })('lee');
    
  3. April 26th, 2011 at 19:36 | #3

    I think you forgot the parens of the g function in this code

    function f(x) {
        function g() {
            return x;
        }
        return g;
    }

    is suppose to be

    function f(x) {
        function g() {
            return x;
        }
        return g();
    }

    no?

  4. April 26th, 2011 at 19:44 | #4

    @Alex Thanks for your comment. No, the point of that function is that it returns another function, not the result of calling that function. g is the function, g() calls the function. I want f to return a function. That’s so I can say:

    var g5 = f(5);
    alert( g5() );
    

    As you can see, g5 is a function, because on the second line I call it. If I’d done return g() inside f, calling f would return the value of x, so in var g5 = f(5); g5 would now just hold the number 5. Hope that makes sense!

  5. Hello71
    April 26th, 2011 at 23:25 | #5
  6. April 27th, 2011 at 00:21 | #6

    @Hello71 Problem? What do you mean?

  7. April 27th, 2011 at 23:04 | #7

    Just asking – do you use closures often in JavaScript? Typically, whole of my code makes use of remembering the scope it’s been defined in (with jQuery it simplifies things a lot), but the actual closures… I don’t remember if I had the real need to do one when working in JS. I’ve created a lot of them in Python when defining decorators, though.

  8. April 28th, 2011 at 10:00 | #8

    @Michal Moroz

    Gah! I thought I’d fixed the UTF-8 thing. I’ve changed your name to avoid the question mark, sorry about that.

    Anyway, yes, I use closures in JavaScript a lot with variously modified versions of the module pattern – the idea is that you define functions in an anonymous function, and return an object with the public functions. E.g. I might do:

    var ThingMaker = function () {
      var privateVar = 10;
      function private () {
      }
      function public1 () {
      }
      function public2 () {
      }
      return {
        public1: public1,
        public2: public2,
      };
    };
    
    var thing = ThingMaker();
    

    So you can call public1 and public2 on thing, and they both have access to private and privateVar, because public1 and 2 are closures with access to the scope of the constructor.

    There’s endless variations on this. The above isn’t really the module pattern per se, but it’s all variations on a theme.

  9. April 28th, 2011 at 13:32 | #9

    The whole point of forcing Java in JavaScript is rather insane to me (creating sophisticated structures to implement the i-dont-trust-my-fellow-coders public/private things), so the example you provided doesn’t convince me. However, I see your point. It could be useful… well, I would follow a convention instead :)

    I see closures as a method of precisation: e.g. you take a general function f and transform it into more precise function g.

  10. April 28th, 2011 at 15:14 | #10

    @Michał Moroz

    It’s funny, I see the use of new in JavaScript as trying to make JS be like Java and failing. I like to have private bits because I think it makes it clearer what the outside world needs to be able to do with the object.

    Yes, your example of turning f into g works as well. Another thing I like to do is have a function with state, e.g.:

    var counter = function () {
      var i = 0;
      return function () {
        i++;
        return i;
      };
    };
    
    counter(); //returns 1
    counter(); //returns 2
    

    You don’t need to make a separate counter object and call its increment method (as you would in Java) – just make a function that has private state through its closure.

  11. Jorge
    April 29th, 2011 at 17:38 | #11
    var counter= (function (i) {
      return function () { return ++i }
    })(0);
    
    counter(); //returns 1
    counter(); //returns 2
    
  12. Jorge
    April 29th, 2011 at 17:45 | #12
    Jorge :
    
    var counter= (function (i) {
      return function () { return ++i }
    })(0);
    
    counter(); //returns 1
    counter(); //returns 2
    

    Oh, I prefer named functions :

    var counter= (function (i) {
      return function counter () { return ++i }
    })(0);
    
  13. February 14th, 2013 at 19:24 | #13

    @Alex

    Alex, no that’s not right. If you say:

    return g();
    

    You’re not actually returning the function “g”, you’re returning whatever result comes back from calling the “g()” function.

    In the example code, the intent was to return the function itself, not that function’s return value.

    Hope this helps…

    Jai

  14. Jonathan
    April 10th, 2013 at 20:55 | #14

    Thanks for your article. It’s quite a mind opener. I really like how by not including the () in [get, set], you’re really passing the functions themselves. And I find it very interesting that the values of the names you pass in are remember; I tried it, and it works, just as you say. But what I don’t get and am trying to understand is why the values are remembered. I think I understand part of it, namely that in JavaScript, functions are also objects, and therefore they can have properties and remember their values if one is calling the same instance. But what I don’t get is why one doesn’t have to explicitly create some sort of property or private static member for it to work. In the example you gave, it sort of works “by magic,” but is there a way to explain why it works…where, how, and why that name value is being held?

  15. June 7th, 2013 at 15:20 | #15

    Hi, just wanted to tell you, I loved this article. It was practical. Keep on posting!

  16. joe
    October 11th, 2013 at 20:01 | #16

    Fuck closures

  17. February 17th, 2014 at 18:02 | #17

    Great good from you, man. I have understand your stuff previous to and you’re just too great. I actually like what you’ve acquired here, certainly like what you are stating and the way iin which you sayy it. You make it enjoysble and yyou still care for to keep it smart. I can not wait to read ffar more from you. This is actually a wonderful website.

  18. Mofo
    March 17th, 2014 at 21:10 | #18

    @joe

    That’s a good way to close everything!

  1. April 30th, 2011 at 16:25 | #1
  2. July 18th, 2011 at 06:13 | #2
  3. September 15th, 2011 at 11:08 | #3
  4. February 5th, 2012 at 03:36 | #4
  5. March 6th, 2012 at 00:55 | #5
  6. December 31st, 2012 at 18:40 | #6
  7. January 24th, 2013 at 05:08 | #7
  8. March 22nd, 2013 at 16:02 | #8
  9. June 25th, 2013 at 12:19 | #9
  10. August 14th, 2013 at 17:31 | #10
  11. January 5th, 2014 at 15:10 | #11
  12. March 31st, 2014 at 14:23 | #12
  13. March 31st, 2014 at 23:03 | #13

Comments parsed as Markdown.