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.
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_namevariable value is retained insideperson()even though the scope callingperson()has redefinedanother_name.@Lee Powers
As I see it (please correct me if I’m wrong), it is not just the value of
another_nameinsideperson(), but full access to the variable that is retained. Person closes over the variableanother_namedeclared in the global object scope, and it is subjected to changes in that variable(see example below).The second use of
another_namein 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:
I think you forgot the parens of the g function in this code
is suppose to be
no?
@Alex Thanks for your comment. No, the point of that function is that it returns another function, not the result of calling that function.
gis the function,g()calls the function. I wantfto return a function. That’s so I can say:As you can see,
g5is a function, because on the second line I call it. If I’d donereturn g()insidef, callingfwould return the value ofx, so invar g5 = f(5);g5would now just hold the number5. Hope that makes sense!Problem: http://kangax.github.com/nfe/
@Hello71 Problem? What do you mean?
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.
@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:
So you can call
public1andpublic2onthing, and they both have access toprivateandprivateVar, becausepublic1and2are 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.
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.
@Michał Moroz
It’s funny, I see the use of
newin 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.:
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.
Oh, I prefer named functions :