Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
102 views

How Do JavaScript Closures Work

Excellent explanations thanks to Stackoverflow.com

Uploaded by

biplabdeka
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
102 views

How Do JavaScript Closures Work

Excellent explanations thanks to Stackoverflow.com

Uploaded by

biplabdeka
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

stackoverflow.

com

http://stackoverflow.com/questions/111102/how-do-javascript-closures-work

How do JavaScript closures work?


Like the old Albert Einstein said:

If you can't explain it to a six-year old, you really don't understand it yourself.

Well, I tried to explain JavaScript closures to a 27-year old friend and completely failed.
How would you explain it to someone with a knowledge of the concepts which make up closures (e.g.
functions, variables and the like), but does not understand closures themselves?
I have seen the Scheme example given in Stack Overflow, and it did not help.
javascript closures

49 Answers
up vote
2175 down
vote
accepted

Whenever you see the function keyword within another function, the inner function has access to
variables in the outer function.
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp)); // will alert
16
}
bar(10);
}
foo(2);
This will always alert 16, because bar can access the x which was defined as an argument to foo,
and it can also access tmp from foo.
That is a closure. A function doesn't have to return in order to be called a closure. Simply accessing
variables outside of your immediate lexical scope creates a closure.
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp)); // will also alert
16
}
}
var bar = foo(2); // bar is now a closure.
bar(10);

The above function will also alert 16, because bar can still refer to x and tmp, even though it is no
longer directly inside the scope.
However, since tmp is still hanging around inside bar's closure, it is also being incremented. It will be
incremented each time you call bar.
The simplest example of a closure is this:
var a = 10;
function test() {
console.log(a); // will output
10
console.log(b); // will output 6
}
var b = 6;
test();
When a JavaScript function is invoked, a new execution context is created. Together with the function
arguments and the parent object, this execution context also receives all the variables declared
outside of it (in the above example, both 'a' and 'b').
It is possible to create more than one closure function, either by returning a list of them or by setting
them to global variables. All of these will refer to the same x and the same tmp, they don't make their
own copies.
Here the number x is a literal number. As with other literals in JavaScript, when foo is called, the
number x is copied into foo as its argument x.
On the other hand, JavaScript always uses references when dealing with Objects. If say, you called
foo with an Object, the closure it returns will reference that original Object!
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing
age.
bar(10);
As expected, each call to bar(10) will increment x.memb. What might not be expected, is that x is
simply referring to the same object as the age variable! After a couple of calls to bar, age.memb will
be 2! This referencing is the basis for memory leaks with HTML objects.

up
JavaScript Closures For Dummies (mirror) is the article that finally got me to understand closures. The
vote explanation posted there is much better than anything I could write here.
1050
down
vote For archiving purposes, I (flying sheep) will put the article from the link below. The article was created
by Morris and put under the Creative Commons Attribution / Share alike license, so Ill recreate it as
close to the original as possible.

JavaScript Closures for Dummies


Submitted by Morris on Tue, 2006-02-21 10:19.

Closures Are Not Magic


This page explains closures so that a programmer can understand them using working JavaScript
code. It is not for gurus or functional programmers.
Closures are not hard to understand once the core concept is grokked. However, they are impossible to
understand by reading any academic papers or academically oriented information about them!
This article is intended for programmers with some programming experience in a mainstream language,
and who can read the following JavaScript function:
function sayHello(name) {
var text = 'Hello ' + name;
var sayAlert = function() { alert(text);
}
sayAlert();
}

An Example of a Closure
Two one sentence summaries:
a closure is the local variables for a function kept alive after the function has returned, or
a closure is a stack-frame which is not deallocated when the function returns (as if a 'stackframe' were malloc'ed instead of being on the stack!).
The following code returns a reference to a function:
function sayHello2(name) {
var text = 'Hello ' + name; // Local
variable
var sayAlert = function() { alert(text); }
return sayAlert;
}
say2 = sayHello2('Bob');
say2(); // alerts "Hello Bob"
Most JavaScript programmers will understand how a reference to a function is returned to a variable in

the above code. If you don't, then you need to before you can learn closures. A C programmer would
think of the function as returning a pointer to a function, and that the variables sayAlert and say2
were each a pointer to a function.
There is a critical difference between a C pointer to a function and a JavaScript reference to a function.
In JavaScript, you can think of a function reference variable as having both a pointer to a function as
well as a hidden pointer to a closure.
function() { alert(text);
The above code has a closure because the anonymous function }
declared inside another function, sayHello2() in this example. In JavaScript, if you use the
function keyword inside another function, you are creating a closure.

is

In C, and most other common languages after a function returns, all the local variables are no longer
accessible because the stack-frame is destroyed.
In JavaScript, if you declare a function within another function, then the local variables can remain
accessible after returning from the function you called. This is demonstrated above, because we call the
function say2() after we have returned from sayHello2(). Notice that the code that we call
references the variable text, which was a local variable of the function sayHello2().
function() { alert(text); } // Output of
say2.toString();
Click the button above to get JavaScript to print out the code for the anonymous function. You can see
that the code refers to the variable text. The anonymous function can reference text which holds the
value 'Bob' because the local variables of sayHello2() are kept in a closure.
The magic is that in JavaScript a function reference also has a secret reference to the closure it was
created in similar to how delegates are a method pointer plus a secret reference to an object.

More examples
For some reason, closures seem really hard to understand when you read about them, but when you
see some examples you can click to how they work (it took me a while). I recommend working through
the examples carefully until you understand how they work. If you start using closures without fully
understanding how they work, you would soon create some very weird bugs!

Example 3
This example shows that the local variables are not copied they are kept by reference. It is kind of
like keeping a stack-frame in memory when the outer function exits!
function say667() {
// Local variable that ends up within
closure
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}
var sayNumber = say667();
sayNumber(); // alerts 667

Example 4

All three global functions have a common reference to the same closure because they are all declared
within a single call to setupSomeGlobals().
function setupSomeGlobals() {
// Local variable that ends up within closure
var num = 666;
// Store some references to functions as global
variables
gAlertNumber = function() { alert(num); }
gIncreaseNumber = function() { num++; }
gSetNumber = function(x) { num = x; }
}
setupSomeGlobals();
gIncreaseNumber();
gAlertNumber(); // 667
gSetNumber(5);
gAlertNumber(); // 5
var oldAlert = gAlertNumber;
setupSomeGlobals();
gAlertNumber(); // 666
oldAlert() // 5
The three functions have shared access to the same closure the local variables of
setupSomeGlobals() when the three functions were defined.
Note that in the above example, if you call setupSomeGlobals() again, then a new closure (stackframe!) is created. The old gAlertNumber, gIncreaseNumber, gSetNumber variables are
overwritten with new functions that have the new closure. (In JavaScript, whenever you declare a
function inside another function, the inside function(s) is/are recreated again each time the outside
function is called.)

Example 5
This one is a real gotcha for many people, so you need to understand it. Be very careful if you are
defining a function within a loop: the local variables from the closure do not act as you might first think.

function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])}
);
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// Using j only to help prevent confusion -- could use i.
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
result.push( function() {alert(item + ' ' +
The line list[i])}
adds a reference to an
anonymous function three times to the result array. If you are not so familiar with anonymous functions
think of it like:
pointer = function() {alert(item + ' ' +
list[i])};
result.push(pointer);
"item3
Note that when you run the example, undefined"
is alerted three times! This is because just
like previous examples, there is only one closure for the local variables for buildList. When the
anonymous functions are called on the line fnlist[j](); they all use the same single closure, and
they use the current value for i and item within that one closure (where i has a value of 3 because the
loop had completed, and item has a value of 'item3').

Example 6
This example shows that the closure contains any local variables that were declared inside the outer
function before it exited. Note that the variable alice is actually declared after the anonymous function.
The anonymous function is declared first; and when that function is called it can access the alice
variable because alice is in the closure. Also sayAlice()() just directly calls the function reference
returned from sayAlice() it is exactly the same as what was done previously, but without the
temporary variable.
function sayAlice() {
var sayAlert = function() { alert(alice); }
// Local variable that ends up within
closure
var alice = 'Hello Alice';
return sayAlert;
}
sayAlice()();

Tricky: note also that the sayAlert variable is also inside the closure, and could be accessed by any
other function that might be declared within sayAlice(), or it could be accessed recursively within the
inside function.

Example 7
This final example shows that each call creates a separate closure for the local variables. There is not a
single closure per function declaration. There is a closure for each call to a function.
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
alert('num: ' + num +
'\nanArray ' + anArray.toString() +
'\nref.someVar ' + ref.someVar);
}
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar:
5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar:
5;

Summary
If everything seems completely unclear then the best thing to do is to play with the examples. Reading
an explanation is much harder than understanding examples. My explanations of closures and stackframes, etc. are not technically correct they are gross simplifications intended to help understanding.
Once the basic idea is grokked, you can pick up the details later.

Final points:
Whenever you use function inside another function, a closure is used.
Whenever you use eval() inside a function, a closure is used. The text you eval can
reference local variables of the function, and within eval you can even create new local
eval('var foo =
variables by using ')
new
When you use Function()
(the Function constructor) inside a function, it does not
create a closure. (The new function cannot reference the local variables of the outer function.)
A closure in JavaScript is like keeping a copy of all the local variables, just as they were when a
function exited.

It is probably best to think that a closure is always created just on entry to a function, and the
local variables are added to that closure.
A new set of local variables is kept every time a function with a closure is called (given that the
function contains a function declaration inside it, and a reference to that inside function is either
returned or an external reference is kept for it in some way).
Two functions might look like they have the same source text, but have completely different
behaviour because of their 'hidden' closure. I don't think JavaScript code can actually find out if a
function reference has a closure or not.
If you are trying to do any dynamic source code modifications (for example:
myFunction =
Function(myFunction.toString().replace(/Hello/,'Hola'));
), it
won't work if myFunction is a closure (of course, you would never even think of doing source
code string substitution at runtime, but...).
It is possible to get function declarations within function declarations within functions and you
can get closures at more than one level.
I think normally a closure is the term for both the function along with the variables that are
captured. Note that I do not use that definition in this article!
I suspect that closures in JavaScript differ from those normally found in functional languages.

Links
Thanks
If you have just learnt closures (here or elsewhere!), then I am interested in any feedback from you
about any changes you might suggest that could make this article clearer. Send an email to
morrisjohns.com (morris_closure @). Please note that I am not a guru on JavaScript nor on
closures.
Thanks for reading.

up vote
965
down
vote

I'm a big fan of analogy and metaphor when explaining difficult concepts, so let me try my hand with a
story.
Once upon a time:
There was a princess...
function princess()
{
She lived in a wonderful world full of adventures. She met her Prince Charming, rode around her world
on a unicorn, battled dragons, encountered talking animals, and many other fantastical things.
var adventures = [];
function princeCharming() { /* ... */
}
var unicorn = { /* ... */ },
dragons = [ /* ... */ ],
squirrel = "Hello!";

But she would always have to return back to her dull world of chores and grown-ups.
return
{
And she would often tell them of her latest amazing adventure as a princess.
story: function() {
return adventures[adventures.length 1];
}
};
}
But all they would see is a little girl...
var littleGirl =
princess();
...telling stories about magic and fantasy.
littleGirl.story();
And even though the grown-ups knew of real princesses, they would never believe in the unicorns or
dragons because they could never see them. The grown-ups said that they only existed inside the little
girl's imagination.
But we know the real truth; that the little girl with the princess inside...
...is really a princess with a little girl inside.
edited Nov 22 '12 at 15:47
Jacob Swartwood

up
vote
239
down
vote

Taking the question seriously, we should find out what a typical 6-year-old is capable of cognitively,
though admittedly, one who is interested in JavaScript is not so typical.
On Childhood Development: 5 to 7 Years it says:

Your child will be able to follow two-step directions. For example, if you say to your child,
"Go to the kitchen and get me a trash bag" they will be able to remember that direction.

We can use this example to explain closures, as follows:

The kitchen is a closure that has a local variable, called trashBags. There is a function
inside the kitchen called getTrashBag that gets one trash bag and returns it.

We can code this in JavaScript like this:


function makeKitchen () {
var trashBags = ['A', 'B', 'C']; // only 3 at
first
return {
getTrashBag: function() {
return trashBags.pop();
}
};
}
var kitchen = makeKitchen();
kitchen.getTrashBag(); // returns trash bag C
kitchen.getTrashBag(); // returns trash bag B
kitchen.getTrashBag(); // returns trash bag A
Further points that explain why closures are interesting:
Each time makeKitchen() is called, a new closure is created with its own separate trashBags.
The trashBags variable is local to the inside of each kitchen and is not accessible outside, but the
inner function on the getTrashBag property does have access to it.
Every function call creates a closure, but there would be no need to keep the closure around
unless an inner function, which has access to the inside of the closure, can be called from outside
the closure. Returning the object with the getTrashBag function does that here.

up vote
145
down
vote

Closures are hard to explain because they are used to make some behaviour work that everybody
intuitively expects to work anyway. I find the best way to explain them (and the way that I learned what
they do) is to imagine the situation without them:
var bind = function(x) {
return function(y) { return x + y;
};
}
var plus5 = bind(5);
alert(plus5(3));
What would happen here if JavaScript didn't know closures? Just replace the call in the last line by its
method body (which is basically what function calls do) and you get:
alert(x +
3);
Now, where's the definition of x? We didn't define it in the current scope. The only solution is to let
plus5 carry its scope (or rather, its parent's scope) around. This way, x is well-defined and it is bound
to the value 5.
answered Sep 21 '08 at 14:24
Konrad Rudolph

up
This is an attempt to clear up several (possible) misunderstandings about closures that appear in some of
vote the other answers.
140
A closure is not only created when you return an inner function. In fact, the enclosing function
down
does not need to return at all in order for its closure to be created. You might instead assign your
vote
inner function to a variable in an outer scope, or pass it as an argument to another function where it
could be called immediately or any time later. Therefore, the closure of the enclosing function is
probably created as soon as the enclosing function is called since any inner function has access to
that closure whenever the inner function is called, before or after the enclosing function returns.
A closure does not reference a copy of the old values of variables in its scope. The variables
themselves are part of the closure, and so the value seen when accessing one of those variables is
the latest value at the time it is accessed. This is why inner functions created inside of loops can be
tricky, since each one has access to the same outer variables rather than grabbing a copy of the
variables at the time the function is created or called.
The "variables" in a closure include any named functions declared within the function. They
also include arguments of the function. A closure also has access to its containing closure's
variables, all the way up to the global scope.
Closures use memory, but they don't cause memory leaks since JavaScript by itself cleans up
its own circular structures that are not referenced. IE memory leaks involving closures are created
when it fails to disconnect DOM attribute values that reference closures, thus maintaining references
to possibly circular structures.
edited Feb 13 '12 at 15:23
dlaliberte

up
vote
The Straw Man
116
down
vote I need to know how many times a button has been clicked, and do something on every third click...

Fairly Obvious Solution


// declare counter outside event handler's
scope
var counter = 0;
var element = document.getElementById('button');
element.onclick = function() {
// increment outside counter
counter++;
if (counter === 3) {
// do something every third time
alert("Third time's the charm!");
// reset counter
counter = 0;
}
};
Now this will work but it does encroach into the outer scope by adding a variable, whose sole purpose is to

keep track of the count. In some situations this would be preferable as your outer application might need
access to this information. But in this case we are only changing every third click's behavior, so it is
preferable to enclose this functionality inside the event handler.

Consider this option


var element = document.getElementById('button');
element.onclick = (function() {
// init the count to 0
var count = 0;
return function(e) {
count++;
`count`

// <- This function becomes the onclick handler


//
and will retain access to the above

if (count === 3) {
// do something every third time
alert("Third time's the charm!");
//reset counter
count = 0;
}
};
})();
Notice a few things here
In the above example I am using the closure behavior of JavaScript. This behavior allows any function
to have access to the scope in which it was created, indefinitely. To practically apply this, I immediately
invoke a function that returns another function, and because the function I'm returning has access to the
internal count variable (because of the closure behavior explained above) this results in a private scope for
usage by the resulting function... Not so simple? Lets dilute it down...
A simple one line closure
//
____________Immediately executed (self
invoked)___________________
//
|
|
//
|
Scope Retained for use
__Returned as the______
|
//
|
only by returned function
| value of func
|
|
//
|
|
|
|
|
|
//
v
v
v
v
v
v
var func = (function() { var a = 'val'; return function() { alert(a); }; })
();
all variables outside the returned function are available to the returned function, but are not directly
available to the returned function object....

func();
"value"
func.a;

// alerts
// undefined

Get it? so in our primary example, the count variable is contianed within the closure and always available
to the event handler, so it retains its state from click to click.
Also this private variable state is fully accessible, for both reading and assigning to it's private scoped
variables.
There you go, you're now fully encapsulating this behavior
Full Blog Post (including jQuery considerations)

up vote
93 down
vote

A closure is much like an object. It gets instantiated whenever you call a function.
The scope of a closure in JavaScript is lexical, which means that everything that is contained within the
function the closure belongs to, has access to any variable that is in it.
A variable is contained in the closure if you
If an inner function (a function contained inside another function) accesses such a variable without
defining it in its own scope with var, it modifies the content of the variable in the outer closure.
A closure outlives the runtime of the function that spawned it. If other functions make it out of the
closure/scope in which they are defined (for instance as return values), those will continue to reference
that closure.

Example

function example(closure){
// define somevariable to live in the closure of
example
var somevariable='unchanged';
return {
change_to:function(value){
somevariable = value;
},
log:function(value){
console.log('somevariable of closure %s is:
%s',
closure, somevariable);
}
}
}
closure_one = example('one');
closure_two = example('two');
closure_one.log();
closure_two.log();
closure_one.change_to('some new value');
closure_one.log();
closure_two.log();

Output
somevariable
somevariable
somevariable
value
somevariable

of closure one is: unchanged


of closure two is: unchanged
of closure one is: some new
of closure two is: unchanged

edited Dec 14 '11 at 0:26


Florian Bsch

up
vote
72
down
vote

Ok, 6-year old closures fan. Do you want to hear the simplest example of closure?
Let's imagine the next situation: driver is sitting in a car. That car is inside a plane. Plane is in the airport.
The ability of driver to access things outside his car, but inside the plane, even if that plane leaves an
airport, is a closure. That's it. When you turn 27, look at the more detailed explanation or at the example
below. Have a nice day!
UPDATE
Here is how I can convert my plane story into the code.
var plane = function (defaultAirport) {
var lastAirportLeft = defaultAirport;
var car = {
driver: {
startAccessPlaneInfo: function () {
setInterval(function () {
console.log("Last airport was " +
lastAirportLeft);
}, 2000);
}
}
};
car.driver.startAccessPlaneInfo();
return {
leaveTheAirport: function (airPortName) {
lastAirportLeft = airPortName;
}
}
}("Boryspil International Airport");
plane.leaveTheAirport("John F. Kennedy");

up vote
63 down
vote

I wrote a blog post a while back explaining closures. Here's what I said about closures in terms of why
you'd want one.

Closures are a way to let a function have persistent, private variables - that is,
variables that only one function knows about, where it can keep track of info from
previous times that it was run.

In that sense, they let a function act a bit like an object with private attributes.
Full post:
So what are these closure thingys?
edited Jan 28 '13 at 2:23
Nathan Long

up vote 52 down
vote

Can you explain closures to a 5 year old?*


I still think Google's explanation works very well and is concise:
/*
*
*
*
*
* An
*/

When a function is defined in another function and it


has access to the outer function's context even after
the outer function returns.
important concept to learn in JavaScript.

function outerFunction(someNum) {
var someString = 'Hey!';
var content = document.getElementById('content');
function innerFunction() {
content.innerHTML = someNum + ': ' + someString;
content = null; // Internet Explorer memory leak for DOM
reference
}
innerFunction();
}
outerFunction(1);
*A C# question

up
vote Closures are simple:
50
down The following simple example covers all the main points of JavaScript closures.*
vote
Here is a factory that produces calculators that can add and multiply:
function make_calculator() {
var n = 0; // this calculator stores a single number
n
return {
add : function (a) { n += a; return n;
},
multiply : function (a) { n *= a; return n;
}
};
}
first_calculator = make_calculator();
second_calculator = make_calculator();
first_calculator.add(3);
second_calculator.add(400);

// returns 3
// returns 400

first_calculator.multiply(11);
second_calculator.multiply(10);
4000

// returns 33
// returns

The key point: Each call to make_calculator creates a new local variable n, which continues to be
usable by that calculator's add and multiply functions long after make_calculator returns.
If you are familiar with stack frames, these calculators seem strange: How can they keep accessing n after
make_calculator returns? The answer is to imagine that JavaScript doesn't use "stack frames", but
instead uses "heap frames", which can persist after the function call that made them returns.
Inner functions like add and multiply, which access variables declared in an outer function **, are called
closures.
That is pretty much all there is to closures.

For example, it covers all the points in the "Closures for Dummies" article given inanother answer, except example 6,
which simply shows that variables can be used before they are declared, a nice fact to know but completely unrelated to
closures. It also covers all the points in the accepted answer, except for the points (1) that functions copy their arguments
into local variables (the named function arguments), and (2) that copying numbers creates a new number, but copying an
object reference gives you another reference to the same object. These are also good to know but again completely
unrelated to closures. It is also very similar to the example in this answer but a bit shorter and less abstract. It does not
cover the point of this answer or this comment, which is that JavaScript makes it difficult to plug thecurrent value of a loop
variable into your inner function: The "plugging in" step can only be done with a helper function that encloses your inner
function and is invoked on each loop iteration. (Strictly speaking, the inner function accesses the helper function's copy of
the variable, rather than having anything plugged in.) Again, very useful when creating closures, but not part of what a
closure is or how it works. There is additional confusion due to closures working differently in functional languages like ML,
where variables are bound to values rather than to storage space, providing a constant stream of people who understand
closures in a way (namely the "plugging in" way) that is simply incorrect for JavaScript, where variables are always bound

to storage space, and never to values.


** Any outer function, if several are nested, or even in the global context, asthis answer points out clearly.

up
Wikipedia on closures:
vote
47
down
In computer science, a closure is a function together with a referencing environment for the
vote
nonlocal names (free variables) of that function.

Technically, in JavaScript, every function is a closure . It always has an access to variables defined in the
surrounding scope.
Since scope-defining construction in JavaScript is a function, not a code block like in many other
languages, what we usually mean by closure in JavaScript is a function working with nonlocal
variables defined in already executed surrounding function.
Closures are often used for creating functions with some hidden private data (but it's not always the case).
var db = (function() {
// Create a hidden object, which will hold the data
// it's inaccessible from the outside.
var data = {};
// Make a function, which will provide some access to the
data.
return function(key, val) {
if (val === undefined) { return data[key] } // Get
else { return data[key] = val } // Set
}
// We are calling the anonymous surrounding function,
// returning the above inner function, which is a closure.
})();
db('x')
// -> undefined
db('x', 1) // Set x to 1
db('x')
// -> 1
// It's impossible to access the data object itself.
// We are able to get or set individual it.
ems
The example above is using an anonymous function, which was executed once. But it does not have to be.
It can be named (e.g. mkdb) and executed later, generating a database function each time it is invoked.
Every generated function will have its own hidden database object. Another usage example of closures is
when we don't return a function, but an object containing multiple functions for different purposes, each of
those function having access to the same data.

up vote 38 down
vote

I put together an interactive JavaScript tutorial to explain how closures work. What's a
Closure?
Here's one of the examples:
var create = function (x) {
var f = function () {
return x; // we can refer to x here!
};
return f;
};
// create takes one argument, creates a
function
var g = create(42);
// g is a function that takes no arguments now
var y = g();
// y is 42 here

edited Jan 28 '13 at 2:25


Nathan Whitehead

up
vote
31
down
vote

How I'd explain it to a six-year old:


You know how grown-ups can own a house, and they call it home? When a mom has a child, the child
doesn't really own anything, right? But it's parents own a house, so whenever someone asks the child
"Where's your home?", he/she can answer "that house!", and point to the house of it's parents. A "Closure"
is the ability of the child to always (even if abroad) be able to say it has a home, even though it's really the
parent's who own the house. :-)
answered Feb 17 at 21:14
Magne

up vote 26 down
vote

You're having a sleep over and you invite Dan. You tell Dan to bring one XBox controller.
Dan invites Paul. Dan asks Paul to bring one controller. How many controllers were brought to
the party?
function sleepOver(howManyControllersToBring) {
var numberOfDansControllers = howManyControllersToBring;
return function danInvitedPaul(numberOfPaulsControllers) {
var totalControllers = numberOfDansControllers +
numberOfPaulsControllers;
return totalControllers;
}
}
var howManyControllersToBring = 1;
var inviteDan = sleepOver(howManyControllersToBring);
// The only reason Paul was invited is because Dan was invited.
// So we set Paul's invitation = Dan's invitation.
var danInvitedPaul = inviteDan(howManyControllersToBring);
alert("There were " + danInvitedPaul + " controllers brought to the
party.");

edited Jul 20 '11 at 15:16


StewShack

up
Example for the first point by dlaliberte:
vote
23
down
A closure is not only created when you return an inner function. In fact, the enclosing
vote
function does not need to return at all. You might instead assign your inner function to a
variable in an outer scope, or pass it as an argument to another function where it could be
used immediately. Therefore, the closure of the enclosing function probably already exists at
the time that enclosing function was called since any inner function has access to it as soon
as it is called.

var i;
function foo(x) {
var tmp = 3;
i = function (y) {
alert(x + y +
(++tmp));
}
}
foo(2);
i(3);

edited Dec 24 '12 at 11:15


someisaac

up
vote
23
down
vote

I tend to learn better by GOOD/BAD comparisons. I like to see working code followed by non-working
code that someone is likely to encounter. I put together a jsFiddle that does a comparison and tries to boil
down the differences to the simplest explanations I could come up with.

Closures done right:


console.log('CLOSURES DONE RIGHT');
var arr = [];
function createClosure(n) {
return function () {
return 'n = ' + n;
}
}
for (var index = 0; index < 10; index++)
{
arr[index] = createClosure(index);
}
for (var index in arr) {
console.log(arr[index]());
}
In the above code createClosure(n) is invoked in every iteration of the loop.

This creates a new scope and n is bound to that scope; this means we have 10 separate scopes,
one for each iteration.
createClosure(n) returns a function that returns the n within that scope.
Within each scope n is bound to whatever value it had when createClosure(n) was invoked so the
nested function that gets returned will always return the value of n that it had when
createClosure(n) was invoked.

Closures done wrong:


console.log('CLOSURES DONE WRONG');
function createClosureArray() {
var badArr = [];
for (var index = 0; index < 10; index++)
{
badArr[index] = function () {
return 'n = ' + index;
};
}
return badArr;
}
var badArr = createClosureArray();
for (var index in badArr) {
console.log(badArr[index]());
}
In the above code the loop was moved within the createClosureArray() function and the function
now just returns the completed array, which at first glance seems more intuitive.
What might not be obvious is that since createClosureArray() is only invoked once only one scope
is created for this function instead of one for every iteration of the loop.
Within this function a variable named index is defined. The loop runs and adds functions to the
array that return index.
Because there was only one scope within the createClosureArray() function, the index variable is
only bound to a value within that scope. In other words, each time the loop changes the value of
index, it changes it for everything that references it within that scope.
All of the functions added to the array return the SAME index variable instead of 10 different ones
from 10 different scopes. The end result is that all 10 functions return the same variable from the
same scope.
After the loop finished and index was done being modified the end value was 10, therefore every
function added to the array returns the value of the single index variable which is now set to 10.

Result
CLOSURES DONE RIGHT
n=0
n=1
n=2
n=3
n=4
n=5

n=6
n=7
n=8
n=9
CLOSURES DONE WRONG
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10

up vote 18
down vote

I know there are plenty of solutions already, but I guess that this small and simple script can be
useful to demonstrate the concept:
// makeSequencer will return a "sequencer" function
var makeSequencer = function() {
var _count = 0; // not accessible outside this
function
var sequencer = function () {
return _count++;
}
return sequencer;
}
var
var
var
var

fnext = makeSequencer();
v0 = fnext();
// v0 = 0;
v1 = fnext();
// v1 = 1;
vz = fnext._count // vz = undefined

answered May 3 '12 at 18:16


Gerardo Lima

up
JavaScript functions can access their:
vote
1. arguments
15
down
2. locals (i.e., their local variables and local functions)
vote
3. environment, which includes:
If a function accesses its environment, then the function is a closure.
Note that outer functions are not required, though they do offer benefits I don't discuss here. By accessing
data in its environment, a closure keeps that data alive. In the subcase of outer/inner functions, an outer

function can create local data and eventually exit, and yet, if any inner function(s) survive after the outer
function exits, then the inner function(s) keep the outer function's local data alive.
Example of a closure that uses the global environment:
Imagine that the StackOverflow Vote-Up and Vote-Down button events are implemented as closures,
voteUp_click and voteDown_click, that have access to external variables isVotedUp and isVotedDown,
which are defined globally. (For simplicity's sake, I am referring to StackOverflow's Question Vote buttons,
not the array of Answer Vote buttons.) When the user clicks the VoteUp button, the voteUp_click function
checks whether isVotedDown == true to determine whether to vote up or merely cancel a down vote.
Function voteUp_click is a closure because it is accessing its environment.
var isVotedUp = false;
var isVotedDown = false;
function voteUp_click()
{
if (isVotedUp)
return;
else if (isVotedDown)
SetDownVote(false);
else
SetUpVote(true);
}
function voteDown_click()
{
if (isVotedDown)
return;
else if (isVotedUp)
SetUpVote(false);
else
SetDownVote(true);
}
function SetUpVote(status)
{
isVotedUp = status;
// do some css stuff to Vote-Up button
}
function SetDownVote(status)
{
isVotedDown = status;
// do some css stuff to Vote-Down
button
}
All four of these functions are closures as they all access their environment.

up
Okay, talking with 6-year old child, I would possibly use following associations.
vote
14
down
Imaging - you are playing with your little brothers and sisters in entire house, you are
vote
moving around with your toys and brought some of them into your older brother's room. After
a while your brother returned from the school and went to his room, and he locked inside it,
so now you could not access toys left there anymore in a direct way. But you could knock
the door and ask your brother for that toys, this is called toy's closure, your brother made it
up for you and he is now into outer scope.

Compare with situation when door was locked by draft and nobody inside (general function execution), and
than some local fire occur and burnt down the room (garbage collector:D), and than new room was build
and now you may leave another toys there (new function instance) but never get the same toys which were
left in first room instance.
For advanced child I would put something like this, it is not perfect but makes you feel about what's it:

function playingInBrothersRoom (withToys) {


// we closure toys which we played in brother's room, when he come back and
lock the door
// your brother suppose to be into outer [[scope]] object now, thanks god
you could communicate with him
var closureToys = withToys || [],
returnToy, countIt, toy; // just another closure helpers, for brother's
inner use
var brotherGivesToyBack = function (toy) {
// new request, there is not yet closureToys on brother's hand yet, give
him a time
returnToy = null;
if (toy && closureToys.length > 0) { // if we ask for specefic toy brother
going search it
for ( countIt = closureToys.length; countIt; countIt--) {
if (closureToys[countIt - 1] == toy) {
returnToy = 'Take your ' + closureToys.splice(countIt - 1, 1) + ',
little boy!';
break;
}
}
returnToy = returnToy || 'Hey, I could not find any ' + toy + ' here,
look for another rooms.';
}
else if (closureToys.length > 0) { // otherwise just give back everything
he has in the room
returnToy = 'Behold! ' + closureToys.join(', ') + '.';
closureToys = [];
}
else {
returnToy = 'Hey, lil shrimp, I gave you everything!';
}
console.log(returnToy);
}
return brotherGivesToyBack;
}
// you are playing in the house, including brother's room
var toys = ['teddybear', 'car', 'jumpingrope'],
askBrotherForClosuredToy = playingInBrothersRoom(toys);
// door is locked, brother came from the shcool, you could not cheat and take
it out directly
console.log(askBrotherForClosuredToy.closureToys); // underfined
// but you could ask your brother politely, to give it back
askBrotherForClosuredToy('teddybear'); // hooray, here it is, teddybear
askBrotherForClosuredToy('ball'); // brother would not be able to find it
askBrotherForClosuredToy(); // brother gives you all the rest
askBrotherForClosuredToy(); // nothing left in there
As you can see, the toys left in the room still accessible via brother and no matter the room is locked. Here
is jsbin to play around it.

edited Apr 26 '13 at 0:16


dmi3y

up vote
12 down
vote

I'd simply point them to the Mozilla Closures page. It's the best, most concise and simple explanation
of Closure basics and practical usage that I've found. Highly recommended to anyone learning
JavaScript.
Edited to add: And yes, I'd even recommend it to a 6-year old -- if the 6-year old is learning about
Closures, then it's logical they're ready to comprehend the concise and simple explanation provided in
the article.
edited Mar 26 '13 at 1:06
mjmoody383

up
vote
10
down
vote

A function in JavaScript is not just a reference to a set of instructions (as in C language) but also includes a
hidden data structure which is composed of references to all nonlocal variables it uses. Such two-piece
functions are called closures. Every function in JavaScript can be considered a closure.
Closures are functions with a state. It is somewhat similar to "this" in the sense that "this" also provides
state for a function but function and "this" are separate objects ("this" is just a fancy parameter, and the only
way to bind it to a function is to create a closure). While "this" and function always live separately, a
function cannot be separated from its closure.
Because all these external variables referenced by a lexically nested function are actually local variables in
the chain of its lexically enclosing functions (global variables can be assumed to be local variables of some
root function), and every single execution of a function creates new instances of its local variables, - every
execution of a function returning (or otherwise transferring it out, such as registering it as a callback) a
nested function creates a new closure (with its own potentially unique set of referenced nonlocal variables
which represent its execution context).
Also, it must be understood that local variables in JavaScript are created not on the stack frame but in the
heap and destroyed only when no one is referencing them. When a function returns, references to its local
variables are decremented but can still be non-null if during the current execution they became part of a
closure and are still referenced by its (lexically) nested functions (which can happen only if the references
to these nested functions were returned or otherwise transferred to some external code).
An example:

function foo (initValue) {


//This variable is not destroyed when the foo function exits.
//It is 'captured' by the two nested functions returned below.
var value = initValue;
//Note that the two returned functions are created right now.
//If the foo function is called again, it will return
//new functions referencing a different 'value' variable.
return {
getValue: function () { return value; },
setValue: function (newValue) { value = newValue; }
}
}
function bar () {
//foo sets its local variable 'value' to 5 and returns an object with
//two functions still referencing that local variable
var obj = foo(5);
//extracting functions just to show that no 'this' is involved here
var getValue = obj.getValue;
var setValue = obj.setValue;
alert(getValue()); //displays 5
setValue(10);
alert(getValue()); //displays 10
//At this point getValue and setValue functions are destroyed
//(in reality they are destroyed at the next iteration of the garbage
collector).
//The local variable 'value' in the foo is no longer referenced by
//anything and is destroyed too.
}
bar();

up
This is copyrighted material so I can't copy it, but I will supply the reference and say that I found it very
vote clear. Chapter 8 section 6, "Closures," of Javascript the Definitive Guide by David Flanagan, 6th edition,
9
O'Reilly, 2011. I'll try to paraphrase.
down
1. When a function is invoked, a new object is created to hold the local variables for that invocation.
vote
2. A function's scope depends on its declaration location, not its execution location.
Now, assume an inner function declared within an outer function and referring to variables of that outer
function. Further assume the outer function returns the inner function, as a function. Now there is an
external reference to whatever values were in the inner function's scope (which, by our assumptions,
includes values from the outer function). Javascript will preserve those values, as they have remained in
scope of current execution thanks to being passed out of the completed outer function. All functions are
closures, but the closures of interest are the inner functions which, in our assumed scenario, preserve
outer function values within their "enclosure" (I hope I'm using language correctly here) when they (the
inner functions) are returned from outer functions. I know this doesn't meet the six-year-old requirement,
but hopefully is still helpful.
edited Apr 25 '13 at 1:56
Jim

up
vote
9
down
vote

An answer for a 6 year old (assuming he knows what a function is and what a variable is, and what data
is):
Functions can return data. One kind of data you can return from a function is another function. When that
new function gets returned, all the variables and arguments used in the function that created it don't go
away. Instead, that parent function "closes." In other words, nothing can look inside of it and see the
variables it used except for the function it returned. That new function has a special ability to look back
inside the function that created it and see the data inside of it.
function the_closure() {
var x = 4;
return function () {
return x; // here, we look back inside the_closure for the value of
x
}
}
var myFn = the_closure();
myFn(); //=> 4
Another really simple way to explain it is in terms of scope:
Any time you create a smaller scope inside of a larger scope, the smaller scope will always be able to see
what is in the larger scope.
answered May 16 '13 at 20:52
Stupid Stupid

up
vote
8
down
vote

I'm sure, Einstein didn't say it with a direct expectation for us to pick any esoteric brainstormer thing and
run over six-year olds with futile attempts to get those 'crazy' (and what is even worse for them-boring)
things to their childish minds :) If I were 6 years old I wouldn't like to have such parents or wouldn't make
friendship with such boring philanthropists, sorry :)
Anyways, for babies, closure is simply a hug, I guess, whatever way you try to explain :) And when you
hug a friend of yours then you both kinda share anything you guys have at the moment. It's a rite of
passage, once you've hugged somebody you're showing her trust and willingness to let her do with you a
lot of things you don't allow and would hide from others. It's an act of friendship :).
Really don't know how to explain it to 5-6 years old babies. I neither think they will appreciate any
JavaScript code snippets like
function Baby(){
this.iTrustYou = true;
}
Baby.prototype.hug = function (baby)
{
var smiles = 0;
if(baby.iTrustYou){
return function(){
smiles++;
alert(smiles);
};
}
};
var
arman = new Baby("Arman")
,morgan = new Baby("Morgana");
var hug = arman.hug(morgan);
hug();
hug();
For children only:
Closure is Hug
Bug is fly
KISS is smooch! :)
answered Jun 5 '13 at 16:39
Arman McHitaryan

up vote
7 down
vote

For a 6y/o?
You and your family live in the mythical town of Ann Ville. You have a friend who lives next door, so you
call them and ask them to come out and play. You dial:

000001 (jamiesHouse)

After a month, you and your family move out of Ann Ville to the next town, but you and your friend still
keep in touch, so now you have to dial the area code for the town that your friend lives in, before dialling
their 'proper' number:

001 000001 (annVille.jamiesHouse)

A year after that, your parents move to a whole new country, but you and your friend still keep in touch,
so after bugging your parents to let you make international rate calls, you now dial:

01 001 000001 (myOldCountry.annVille.jamiesHouse)

Strangely though, after moving to your new country, you and your family just so happen to move to a
new town called Ann Ville... and you just so happen to make friends with some new person called
Jamie... You give them a call...

000001 (jamiesHouse)

Spooky...
So spooky in fact, that you tell Jamie from your old country about it... You have a good laugh about it. So
one day, you and your family take a holiday back to the old country. You visit your old town (Ann Ville),
and go to visit Jamie...

02 001 000001 (myNewCountry.annVille.jamiesHouse)

Opinions?
What's more, I have a load of questions about the patience of a modern 6y/o...
edited May 9 '13 at 23:59
Charlie

up vote
7 down
vote

Given the following function

function person(name, age){


var name=name;
var age=age;
function introduce(){
alert("My name is "+name+", and I'm
"+age);
}
return introduce;
}
var a = person("Jack",12);
var b = person("Matt",14);
Everytime the function person is called a new closure is created. While variables a and b have the
same introduce function, it is linked to different closures. And that closure will still exist even after the
function person finishes execution.

a(); //My name is Jack, and I'm


12
b(); //My name is Matt, and I'm
14
An abstract closures could be represented to something like this

closure a = {
name: "Jack",
age: 12,
call: function introduce(){
alert("My name is "+name+", and I'm
"+age);
}
}
closure b = {
name: "Matt",
age: 14,
call: function introduce(){
alert("My name is "+name+", and I'm
"+age);
}
}

Assuming you know how a class in another language work. I will make an analogy.
Think like
Everytime a function is called

up
vote
6
down
vote

After a function is invoked, it goes out of scope. If that function contains something like a callback function,
then that callback function is still in scope. If the callback function references some local variable in the
immediate environment of the parent function, then naturally you'd expect that variable to be inaccesible to
the callback function and return undefined.
Closures ensure that any property that is referenced by the callback function is available for use by that
function, even when it's parent function may have gone out of scope
answered Jul 25 '12 at 21:26
IQ_HiGh

protected by Community Sep 19 '11 at 16:35


Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now
requires 10 reputation on this site.
Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged javascript
closures or ask your own question.
site design / logo 2014 stack exchange inc; user contributions licensed under cc by-sa 3.0 with attribution required

You might also like