A Graphical Explanation Of Javascript Closures In A jQuery Context

Posted February 4, 2009 at 10:10 AM by Ben Nadel

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.




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 »
10,640 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 »
24 Comments

Looking forward to the presentation next week!


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

@Aaron,

Oh heck yeah!


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

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


Jim
Feb 4, 2009 at 8:48 PM // reply »
8 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 »
8 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 »
3 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 »
10,640 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!


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 »
10,640 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.


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 »
10,640 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 »
10,640 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 »
10,640 Comments

@Andrew,

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


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 »
10,640 Comments

@Zorg,

Do you have a link to the Ungar paper?


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


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


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

This was great to understand. Thank you


Nov 29, 2009 at 8:00 PM // reply »
1 Comments

I think jQuery convert all the $("a") into objects.

and then jLinks.each assign jThis.click method to each of the "a" objects.


Jul 8, 2010 at 6:20 PM // reply »
1 Comments

Thank you, that's the best explanation I have seen.


Jul 10, 2010 at 5:45 PM // reply »
1 Comments

Thanks for this, nice bit of graphical explanation but now I need to know more... :)


Jul 12, 2010 at 10:49 AM // reply »
10,640 Comments

@Joel, @Julian,

Glad you guys are liking it.


Aug 16, 2010 at 2:19 PM // reply »
3 Comments

Images aren't appearing!


Aug 16, 2010 at 9:11 PM // reply »
10,640 Comments

@Richard,

My server has been having some issues lately. Try hitting this blog post again and it should work. Sorry about the dips in performance.


May 18, 2011 at 12:23 PM // reply »
1 Comments

I especially liked your site posts, and so on through all of them beautiful


Oct 17, 2011 at 11:52 AM // reply »
1 Comments

I loved this explanation of closure with scope-chaining. Clearest ever article on closure!!!
Thanks Ben

vimal
Germany


seb
Nov 23, 2011 at 1:53 AM // reply »
1 Comments

man, this was clear. As I m getting more into JavaScript seriously, I realize that I can see the big picture more easily and It makes me really damn happy.I thought that closures were more complicated than that.Man, javascript is awesome. It really is the punk rock language!


Jan 27, 2012 at 10:42 AM // reply »
4 Comments

Ben,

Loved this.... I recommended it to several folks who (like me) tend to see closures as just out of reach mentally :)

-Mark



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »