A Graphical Explanation Of Javascript Closures In A jQuery Context

Posted February 4, 2009 at 10:10 AM

Tags: Javascript / DHTML

Over the weekend, I was working on my in-depth jQuery presentation for the New York ColdFusion User Group. As part of the presentation, I wanted to discuss the beauty of Javascript "closures" and how jQuery makes tremendous use of them. Javascript closures can be a very hard thing to wrap your head around, especially when you are faced with vague definitions like:

A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).

I mean, come on, what the heck does that mean? I know a bit about closures and that definition doesn't make sense to me. Like I said, closures can be a hard thing to really understand. As such, I wanted to try and explain them [closures] with the help of some graphics because, as they say, a picture is worth a thousand words.

First, let's look a simple jQuery demo:


 
 
 

 
Javascript Closure Explanation - Plain Method Code.  
 
 
 

In this code, we are adding click event handlers to all of the links in the document. These click event handlers, when triggered, will alert the index of the given link in the context of the entire set of document links. Of course, the intent of the code is secondary to the demonstration. What's of primary importance here is structure of the code. Take a look at the functions that are being defined:


 
 
 

 
Javascript Closure Explanation - Nested Methods Outlined.  
 
 
 

Notice that we are defining three anonymous methods in this demo. Each of these methods is defined within a parent context. The outer-most method is defined in the context of the window (theoretically based on the visible code); the middle method is defined in the context of the outer-most method; and the inner-most method is defined in the context of the middle method.

In Javascript, a given context always has access to its parent context. To be honest, the mechanisms behind this visibility are a bit beyond my purview, but I know it has something to do with scope chains (or is it prototype chains - definitely some sort of chain). As such, each method in our demonstration has access not only to its locally defined variables, but also the variables available in its parent context:


 
 
 

 
Javascript Closure Explanation - Methods Have Access To Their Parent Context.  
 
 
 

Notice that in the inner-most method, it has to move up one scope in the parent chain to find "intLinkIndex," but it has to move up two scopes in the chain to find the "jLinks" variable. While it might not be obvious, the two-parent-context-jump is following the same exact rules - first, the inner-most method looks for jLinks in its own context. Since it's not a local variable, it can't find it. Then, it asks its parent context (the middle method) for the variable. The middle method checks its local scope and can't find it, so it passes this request up to its parent context, the outer-most method. And, because each context has access to its parent context, this variable request is easily passed up the context chain.

Ok, so far so good; now, let's really get into closures. Keeping this whole parent context concept in mind, take a look at where these defined methods are ending up:


 
 
 

 
Javascript Closure Explanation - Each Method Definition Is Passed Out Of Its Parent Context.  
 
 
 

As we are defining these anonymous methods, we are using the each() method and the click() method to pass these functions away from their parent context. Where are they going? We don't know - they're being passing into another context altogether. Sure, from the demo code, it looks like they are getting passed to jLinks and jThis respectively; but, the fact is, once these method references are passed into those foreign contexts, we can't say with certainty how they are being used. Are they transient? Are they being cached somehow in the window object for the entire life of the page?

These are questions that we can't answer; but, more importantly, these are also questions that the browser's memory management system can't answer (speaking with personification). And, because it doesn't know where these methods are ending up, it can't garbage collect (destroy) the original parent context of the method definitions. That's the power and beauty of the Javascript closure right there - see, even though the methods are being passed away from their original context, due to the scope chains in place, they still have access to their parent context and to all the variables available in their parent context.

So, the real message to take away here is that when you pass a method reference out of the context in which it was defined, the method still has access to its parent context. And, once you understand and embrace this, it can be leveraged in some really cool ways (as seen in this jQuery example). This is not the most in-depth explanation of closures, but hopefully these graphics have helped you to better understand the closure mechanism.

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page




Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Feb 4, 2009 at 10:48 AM // reply »
2 Comments

Ben: Good explanation -- one of the best explanations I've seen.

There is also a great video on Advaned JS by Douglas Crockford that goes into details on how this works behind the scenes. Check it out.. its available in the YUI theater: http://video.yahoo.com/watch/111585/1027823


Feb 4, 2009 at 11:00 AM // reply »
153 Comments

I second Brian's comment. As I was reading through the post I was thinking I'd have to find the same video.

Pretty much all of the Crockford videos on Yahoo! are worth your time. Some of them get mind-bendingly complex, but they'll really open your eyes.

Having said all of that, I'll also say that your post is an excellent explanation of a very confusing concept. Very nicely done.


Feb 4, 2009 at 11:21 AM // reply »
6,371 Comments

Thanks guys. I'll have to check out the YUI videos. I think I went there once and was just overwhelmed with the amount of content :) Time to get over that fear!


Feb 4, 2009 at 2:29 PM // reply »
10 Comments

Looking forward to the presentation next week!


Feb 4, 2009 at 2:31 PM // reply »
6,371 Comments

@Aaron,

Oh heck yeah!


Feb 4, 2009 at 3:28 PM // reply »
7 Comments

You're a star!!! That's a really good explanation!!!!!!!! Thanks for that Ben


Jim
Feb 4, 2009 at 8:48 PM // reply »
2 Comments

What makes most of this possible is that JavaScript is "lexically scoped." This means that something is in the scope in which it was defined--not where it ends up. Wherever I wrote the function, it is in (and stays in) that scope.

Lexical scoping and lambda (anonymous) functions combined with JavaScript's awesome chaining capabilities also make for some brilliant ways to namespace your projects and emulate class-like method/property access-control (i.e. public and private). It is what makes jQuery possible!

Once you wrap your head around these concepts, JavaScript becomes a sexy and extremely flexible and powerful language. Yes, I called a programming language sexy!


Jim
Feb 4, 2009 at 8:50 PM // reply »
2 Comments

...continued from my previous comment...

I forgot to add that the chaining capabilities allow for "self executing" lambdas which is one of the coolest namespacing tools available.


Feb 5, 2009 at 10:17 AM // reply »
1 Comments

Great explanation, love the images. Nice to see such a pragmatic explanation, without to much detail to confuse the topic.


Feb 5, 2009 at 2:04 PM // reply »
6,371 Comments

@Jim,

I have seen one or two examples of public/private emulation with Javascript. At the time, I didn't understand enough Javascript to see how that was working. Maybe it would be different now.

Yeah, it is sexy stuff!


zorg
Feb 10, 2009 at 11:05 AM // reply »
3 Comments

A very thorough explanation of Javascript closures can be found here (take a deep breath) :
http://www.jibbering.com/faq/faq_notes/closures.html

> A "closure" is an expression (typically a function) that can have free
> variables together with an environment that binds those variables (that
> "closes" the expression).
> I mean, come on, what the heck does that mean? I know a bit about
> closures and that definition doesn't make sense to me.

too bad, because it's exactly what a closure is !
Free variables are identifiers in the function body that are not parameters.
An environment is a list of names and their associated values, used to evaluate expressions.
So there you have it : a closure is an expression that can look up an environment for the values of its free variables or , to use your own terms, an expression that has "access to their parent context"

> As we are defining these anonymous methods, we are using the each()
> method and the click() method to pass these functions away from their
> parent context. Where are they going? We don't know - they're being
> passing into another context altogether. Sure, from the demo code, it
> looks like they are getting passed to jLinks and jThis respectively; but,
> the fact is, once these method references are passed into those foreign
> contexts, we can't say with certainty how they are being used. Are
> they transient? Are they being cached somehow in the window object
> for the entire life of the page? These are questions that we can't answer...

they can be answered though :
in the case of jThis, the anonymous function is registered as a handler for the onclick event (think about it as being referenced by the <a> element itself)
in the case of jLinks, the anonymous function is executed for each (index, obj) in jLinks, ... maybe that's what you call transient ? In any case once that block has executed, that function is gone...


Feb 10, 2009 at 11:10 AM // reply »
6,371 Comments

@Zorg,

That is a great link and is, in fact, where I got the original definition for closures.

As far as where the functions go, I am sorry if I did not communicate well; I understand that yes, we can look into the Click event wiring and actually see where it goes; what I mean to get across in a more abstract way is that when a method is passed out of its parent context, we should not assume anything about where it goes or how long it lives. And, in doing so, we can start to become comfortable with the idea that the variables in its parent scope must be kept around in case the method reference is ever executed.

I wanted to get people comfortable with the idea of closures at a high level, not so much with the specifics of the behind the scenes.


Zorg
Feb 10, 2009 at 11:46 AM // reply »
3 Comments

@Ben

> I wanted to get people comfortable with the idea of closures at a high
> level, not so much with the specifics of the behind the scenes.

Sorry, I missed that :)


Feb 10, 2009 at 11:50 AM // reply »
6,371 Comments

@Zorg,

Nothing to be sorry about at all my friend. Closures are a really complex concept for people to get. The more insight that people such as yourself can offer, the better off we all are going to be.


DL
Feb 20, 2009 at 4:45 PM // reply »
1 Comments

Too complicated.

Where did you learn this? Do you know of any good resource or book for learning functional JavaScript from ground-up?


FM
Feb 22, 2009 at 9:02 AM // reply »
1 Comments

@dl

JavaScript: The Good Parts
Unearthing the Excellence in JavaScript
By Douglas Crockford

This is good to learn and many thanks to Douglas.


Feb 22, 2009 at 9:32 AM // reply »
6,371 Comments

@FM,

I've heard that that is a very good book.


May 8, 2009 at 4:19 PM // reply »
1 Comments

I've translated your article into Russian. Thought you don't mind.
All the backlinks are proveded. Here is the full version: http://interpretor.ru/js_closures/
Thank you for the great article!


May 8, 2009 at 5:48 PM // reply »
6,371 Comments

@Andrew,

That's awesome!! Glad you felt it was worthy :)


zorg
May 11, 2009 at 5:23 AM // reply »
3 Comments

+1 Douglas Crockford : this is the best book about the functional core of JS. (don't miss his videos 7 on Javascript + 3 on DOM).

for the OO model of Javascript see Liberman paper on prototype-based inheritance and see the papers on Self by Ungar.

all this is freely available online


May 11, 2009 at 9:03 AM // reply »
6,371 Comments

@Zorg,

Do you have a link to the Ungar paper?


zorg
May 24, 2009 at 1:08 PM // reply »
2 Comments

http://selflanguage.org/documentation/published/index.html

Self the power of simplicity, is a good place to start


zorg
May 24, 2009 at 1:12 PM // reply »
2 Comments

http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html

for the Lieberman paper


Sanketh
Jun 3, 2009 at 4:11 PM // reply »
1 Comments

This was great to understand. Thank you


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 7, 2009 at 5:53 PM
Ask Ben: Javascript String Replace Method
You can find here an advanced function that prepared with javascript replace function. This can make the first letters of words, sentences, lines and whatever you define automatically: http://www.m ... read »
Andrew Neely
Nov 7, 2009 at 4:56 PM
A Moment That Touched Me - The Fountainhead
Ben, Glad you enjoyed the podcast. Yeah, the Tank Riot guys can get really chatty during the episodes, but that's part of the charm of it for me. They've covered everything from Nichola Tesla to Cha ... read »
Nov 7, 2009 at 4:43 PM
Building A Fixed-Position Bottom Menu Bar (ala FaceBook)
Is it possible to make some more MenĂ¼`s ? ... read »
Jill
Nov 7, 2009 at 11:40 AM
How To Unformat Your Code (Like A Pro)
Derek, I think you might be right - sweet! Thanks for the link :) ... read »
Nov 7, 2009 at 11:25 AM
How To Unformat Your Code (Like A Pro)
I think it would be way easier to just use this http://www.logichammer.com/html-formatter/ He just released v3 and it rocks. ... read »
Jill
Nov 7, 2009 at 7:58 AM
How To Unformat Your Code (Like A Pro)
LMAO - this was pretty funny! I have to admit - I also love to reformat code so I can read it. My boss used to tell me to leave my OCD at home. Now I don't feel so bad after reading everyone else' ... read »
Nov 6, 2009 at 10:10 PM
How To Unformat Your Code (Like A Pro)
The timing of this post is just uncanny. I spent the last 15-20 minutes manually un-formatting my "Ben Nadel" style code within a CFC of mine. I was really digging the readability a few weeks ago, bu ... read »
Roe
Nov 6, 2009 at 5:11 PM
Passing Arrays By Reference In ColdFusion - SWEEET!
ArraySort also reorders the results of these java obj's ... read »