

How do JavaScript closures work? - abraham
http://stackoverflow.com/q/111102/26406

======
aufreak3
For a mental model, pretend that variables are referring to storage locations
in an array and you reference them using indices - v = [..., v[100], v[101],
v[102], v[103], ....]

For example, take the function in the stackoverflow answer -

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

When you make a call to foo(10), pretend that the bound variables in the body
of the function get assigned sequence numbers starting from 100 -

    
    
      function foo() {
        v[100] = 10; // x = 10
        v[101] = 3;  // var tmp = 3;
    
        return function (y) {
          alert(v[100] + y + (++(v[101])));
        }
      }
    

So you get as the result,

    
    
      function (y) {
         alert(v[100] + y + (++(v[101])));
      }
    

'y' remains as such because it hasn't been bound to a value just yet. That
will happen only when you _call_ this result function.

Now, when you call foo another time like foo(20), the sequence continues from
102 ...

    
    
      function foo() {
        v[102] = 20; // x = 20
        v[103] = 3;  // var tmp = 3;
    
        return function (y) {
          alert(v[102] + y + (++(v[103])));
        }
      }
    

So you get _another_ function as the result -

    
    
      function (y) {
         alert(v[102] + y + (++(v[103])));
      }
    

The store now reads v[100] = 10, v[101] = 3, v[102] = 20 and v[103] = 3.

It becomes clear what the two result functions do. Note that they do not share
the same storage locations and therefore the two ++ calls increment
_different_ storage locations.

In this model, each "var" statement and each argument of a function causes the
index assigned to be incremented on a function call, and unbound variables do
not cause increments. The behaviour of closures created in javascript is as
though such an indefinitely increasing numbering scheme is being used under
the hood.

(edited a bit for clarity).

~~~
vaughanhedges
'y' remains as such because it hasn't been bound to a value just yet.

That's easy enough to test. var y=20;

    
    
      function foo(x) {
      var tmp = 3;
      var y = 20;
      return function (y) {
        alert(x + y + (++tmp));
      }

}

var bar = foo(2); // bar is now a closure.

bar(10);

This makes no difference. The alert runs once, and displays 16.

------
raganwald
Let's make closures easy:

[https://github.com/raganwald/homoiconic/blob/master/2010/10/...](https://github.com/raganwald/homoiconic/blob/master/2010/10/let.md#readme)

~~~
stanleydrew
Great stuff. Do you accept pull requests?

~~~
raganwald
Wouldn't that depend on the request? But seriously, it's a Git repo. Send a
request!

~~~
spicyj
I think the question was more, "Do you consider pull requests?"

------
csomar
For those who wonder how useful JavaScript closures can be. They are very
useful. Take a simple pattern. You are iterating through a statement, and you
want to use the variable _i_ of the statement in another function.

    
    
      for (var i = 0; i < 5; i++) {
        console.info(i);
      }
    

This works fine. And the console displays 1, 2, 3 and 4. But let's suppose
that you have the following code:

    
    
      for (var i = 0; i < 5; i++) {
        $(DOMelement:eq(i)).click(function() {
          console.info(i);
        });
      }
    

The console will always display "4" whichever DOMelement you clicked.
Surprise? That's because it calls _i_ which holds 4. JavaScript passed the
argument by reference to i and by the time you clicked, the iterations already
finished.

JavaScript closures help solve this problem (Luckily). Here is how:

    
    
      for (var i = 0; i < 5; i++) {
        $(DOMelement:eq(i)).click(function() {
         return function() {
          console.info(i);
         }
        });
      }
    

That's because JavaScript returns now a new function for each DOM element.
Each new function holds the _i_ value while iteration and now the final value.

~~~
anc2020
I'm not sure your code does as intended, won't the function be called only
once the element is clicked?

This should work okay:

    
    
      for (var i = 0; i < 5; i++) {
        $(DOMelement:eq(i)).click((function(i) {
         return function() {
          console.info(i);
         }
        }(i)));
      }
    

Also surely DOMelement.eq(i) as opposed to DOMelement:eq(i)?

~~~
sdevlin
I think you're correct. His interior function is still just another closure
around the original _var i_.

Also, this feels like piling on, but I think the original (intentionally
erroneous) example would print '5' repeatedly rather than '4'. _var i_ ends up
with the value _5_.

------
seliopou
If you _really_ want to know how JavaScript closures work:

<https://github.com/brownplt/LambdaJS>

------
skrebbel
A closure is the hotel room key that you kept so you could always access all
items you hid in there, and the hotel personnel cooperating with the whole
ordeal.

------
anc2020
Hi, I wrote the accepted answer and welcome changes or suggestions (it's
community wiki).

------
reichstein
Javascript closures are more fun than most other languages, because the scope
chain can be changed after the closure has been created. Try explaining this
to a 6-year old:

function foo(o) { eval("var x = 10;"); with (o) { return function(e) { if
(typeof e == "string") eval(e); return x; } } } this.x = 42; var f = foo({x :
37}); alert(f("var x = 13")); alert(f()); alert(f("delete x"));
alert(f("delete x"));

Each call returns a different variable called "x".

------
euroclydon
Could be expanded further to describe when generating multiple functions, each
with a reference to an object is a useful design pattern in JavaScript, and
when it's a common mistake.

~~~
anc2020
Could do, but the aim of my answer was to keep it short and simple and not a
full reference to closures (there are some good links on this page with more
detail for that).

------
dkastner
I've found that using function compositions/closures for event handling makes
my JS code much more testable and readable:
[http://numbers.brighterplanet.com/2011/06/10/a-pattern-
for-j...](http://numbers.brighterplanet.com/2011/06/10/a-pattern-for-
javascript-events/)

------
jberryman
If we learned to program in lisp, scheme, haskell, or some other language with
(dare i say?) sane semantics we'd be wondering what all the fuss about
closures was:

<http://www.haskell.org/haskellwiki/Closure>

------
stanleydrew
This explanation is the most thorough I've found. It also happens to be the
first Google result for "javascript closures".

<http://jibbering.com/faq/notes/closures/>

------
ptio
I like how Douglas Crockford explained it here:
<http://www.youtube.com/watch?v=hQVTIJBZook#t=27m20s>

