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!

  19. May 18th, 2014 at 09:04 | #19

    If you cat is a completely indoor cat, then there little chance of feline leukemia and he or she probably doesn’t require that vaccine. 0, Scientific News Service Social Networking and Medical News Service Social Networking.

    If you might have a pair of those jeans, drop me a line and I will get a pair of these, or maybe even two when you have several colors available. It is often a good idea to transmit your letter as soon as you get the news. source [source](http://is.gd/49Qh4z “source”) Observance with the conventions of writing having an academic tone will ensure your writing has credibility and are seen as being a serious and respected writer. For instance, on the end with the formal letter you should put: ”.

  20. May 19th, 2014 at 01:39 | #20

    In order to cherish news from different spheres of life, you don. In fact, we ourselves change this news channel, if we’re presented with same news the complete day.

    The organizations that are involved in rendering content writing services are supported by team of diligent and efficient content writers and editors. If your description exceeds 25 words, the form is not going to successfully submit.

    [http://tiny.cc/c758cx](http://tinyurl.com/mftkkjv “http://tiny.cc/c758cx”) article As a rule, your artist’s statement needs to be written within the first person. This is one kind of my favorite websites as they have so many excellent free printable cursive handwriting worksheets.

  21. May 19th, 2014 at 16:38 | #21

    Have you ever thought about creating an e-book or guest authoring on other websites? I have a blog based upon on the same topics you discuss and would really like to have you share some stories/information. I know my audience would appreciate your work. If you are even remotely interested, feel free to shoot me an email.

    Make sure to address each risk’s chance of occurring along with its impact for the project and the organization. In order to inspire an easy moving and excited feeling inside mind of reader, you are able to use various techniques. [you may](http://tiny.cc/wsrtfx “you may”) surefire x300 glock 23 It doesn’t matter if you happen to be writing for promotional purposes, website content, or post in your blog. If they charge through the word or even the page, let them know what your ceiling is and ask these to contact you before exceeding that limit.

  22. June 28th, 2014 at 15:05 | #22

    Today, I went to the beachfront with my kids. I found a sea shell and gave it to my 4 year old daughter and said “You can hear the ocean if you put this to your ear.” She put the shell to her ear and screamed. There was a hermit crab inside and it pinched her ear. She never wants to go back! LoL I know this is entirely off topic but I had to tell someone!

  23. October 6th, 2014 at 14:52 | #23

    Hi! I just wanted to ask if you ever have any issues with hackers? My last blog (wordpress) was hacked and I ended up losing several weeks of hard work due to no data backup. Do you have any solutions to stop hackers?

  24. October 8th, 2014 at 19:47 | #24

    Hi! This post could not be written any better!

    Reading through this post reminds me of my previous room mate! He always kept chatting about this.

    I will forward this write-up to him. Fairly certain he will have a good read. Thanks for sharing!

  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
  14. May 10th, 2014 at 08:26 | #14
  15. May 13th, 2014 at 05:04 | #15
  16. May 14th, 2014 at 07:10 | #16
  17. June 5th, 2014 at 04:50 | #17
  18. September 21st, 2014 at 04:35 | #18
  19. December 7th, 2014 at 19:34 | #19

Comments parsed as Markdown.