Explaining JavaScript scope and closures
I thought I’d try to explain something which many people struggle with: JavaScript scope and closures.
Background
There are a number of articles and blog posts out there trying to explain scope and closures, but overall I’d say that a majority of them aren’t crystal-clear. Besides, a number of them take for granted that everyone has developed in about 15 other languages before, while my experience is that a lot of people writing JavaScript come from a HTML and CSS background, instead of C and Java.
Therefore, my humble goal with this article is for everyone to finally grasp what scope and closures are, how they works, and especially how you can benefit from them. You do need to understand the basic concepts of variables and functions before reading this.
Scope
Scope refers to where variables and functions are accessible, and in what context it is being executed. Basically, a variable or function can be defined in a global or local scope. Variables have so-called function scope, and functions have the same scope as variables.
Global scope
When something is global means that it is accessible from anywhere in your code. Take this for example:
var monkey = "Gorilla";
function greetVisitor () {
return alert("Hello dear blog reader!");
}
If that code was being run in a web browser, the function scope would be window, thus making it available to everything running in that web browser window.
Local scope
As opposed to the global scope, the local scope is when something is just defined and accessible in a certain part of the code, like a function. For instance;
function talkDirty () {
var saying = "Oh, you little VB lover, you";
return alert(saying);
}
alert(saying); // Throws an error
If you take a look at the code above, the variable saying is only available within the talkDirty function. Outside of it it isn’t defined at all. Note of caution: if you were to declare saying without the var keyword preceding it, it would automatically become a global variable.
What this also means is that if you have nested functions, the inner function will have access to the containing functions variables and functions:
function saveName (firstName) {
function capitalizeName () {
return firstName.toUpperCase();
}
var capitalized = capitalizeName();
return capitalized;
}
alert(saveName("Robert")); // Returns "ROBERT"
As you just saw, the inner function capitalizeName didn’t need any parameter sent in, but had complete access to the parameter firstName in the outer saveName function. For clarity, let’s take another example:
function siblings () {
var siblings = ["John", "Liza", "Peter"];
function siblingCount () {
var siblingsLength = siblings.length;
return siblingsLength;
}
function joinSiblingNames () {
return "I have " + siblingCount() + " siblings:\n\n" + siblings.join("\n");
}
return joinSiblingNames();
}
alert(siblings()); // Outputs "I have 3 siblings: John Liza Peter"
As you just saw, both inner functions have access to the siblings array in the containing function, and each inner function have access to the other inner functions on the same level (in this case, joinSiblingNames can access siblingCount). However, the variable siblingsLength in the siblingCount is only available within that function, i.e. that scope.
Closures
Now when you hopefully have gotten a better grasp of what scope is, let’s add closures to the mix. Closures are expressions, usually functions, which can work with variables set within a certain context. Or, to try and make it easier, inner functions referring to local variables of its outer function create closures. For instance:
function add (x) {
return function (y) {
return x + y;
};
}
var add5 = add(5);
var no8 = add5(3);
alert(no8); // Returns 8
Whoa, whoa! What just happened? Let’s break it down:
- When the add function is called, it returns a function.
- That function closes the context and remembers what the parameter x was at exactly that time (i.e. 5 in the code above)
- When the result of calling the add function is assigned to the variable add5, it will always know what x was when it was initially created.
- The add5 variable above refers to a function which will always add the value 5 to what is being sent in.
- That means when add5 is called with a value of 3, it will add 5 together with 3, and return 8.
So, in the world of JavaScript, the add5 function actually looks like this in reality:
function add5 (y) {
return 5 + y;
}
The infamous loop problem
How many times have you created some sort of loop where you wanted to assign the value of i in some way, e.g. to an element, and found out it just returned the last value i had?
Incorrect reference
Let’s take a look at this faulty code, which creates 5 a elements, adds the value of i as a text to each element and an onclick which is expected to alert the value of i for that link, i.e. the same value as in the a element’s text. It then appends them to your document body:
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function () {
alert(i);
};
document.body.appendChild(link);
}
}
window.onload = addLinks;
Each a element gets the correct text, i.e. “Link 0″, “Link 1″ and so on. But whichever link you click, it alerts the number “5″. Oh my God, why? The reason for this is that the variable i get its value increased with 1 for each iteration of the loop, and since the onclick event isn’t being executed, just applied to the a element, it adds up.
Therefore, the loop continues until i is 5, which is the last value of i before the function addLinks exits. Then, whenever the onclick event is actually being triggered, it takes the last value of i.
Working reference
What you want to do instead is create a closure, so that when you apply the value of i to the onclick event of the a element, it gets the exact value of i at just that moment in time. Like this:
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function (num) {
return function () {
alert(num);
};
}(i);
document.body.appendChild(link);
}
}
window.onload = addLinks;
With this code, if you click the first a element it will alert “0″, the second “1″ etc; just what you probably expected with the first code I showed you to do. The solution here is that the inner function of what’s applied to the onclick event create a closure where it references the parameter num, i.e. what the i variable is at just that time.
That function then closes with that value safely tucked away, and can then return its corresponding number when the onclick event is being called.
Self-invoking functions
Self-invoking functions are functions who execute immediately, and create their own closure. Take a look at this:
(function () {
var dog = "German Shepherd";
alert(dog);
})();
alert(dog); // Returns undefined
Ok, so the dog variable was only available within that context. Big deal, man, hidden dogs… But, my friends, this is where it becomes really interesting! It solved our problem with the loop above, and it is also the base for the Yahoo JavaScript Module Pattern.
Yahoo JavaScript Module Pattern
The gist of the pattern is that it uses a self-invoking function to create a closure, hence making it possible to have private and public properties and methods. A simple example:
var person = function () {
// Private
var name = "Robert";
return {
getName : function () {
return name;
},
setName : function (newName) {
name = newName;
}
};
}();
alert(person.name); // Undefined
alert(person.getName()); // "Robert"
person.setName("Robert Nyman");
alert(person.getName()); // "Robert Nyman"
The beauty of this is that you now can decide on your own what will be publicly visible for your object (and can be overwritten), and what is private and no one can access nor alter. The variable name above is hidden outside the context of the function, but accessible from the returned getName respectively setName functions, since they create closures where they have a reference to the name variable.
Conclusion
My sincere hope is that after reading this, novice or experienced programmer, you have gotten a clear view of how scope and closures actually work in JavaScript. Questions and feedback are very welcome, and if any input is deemed important enough, I will update this article with it.
Happy coding!

74 Comments/Reactions
October 9th, 2008 at 20:40
Thanks for explaining JS closures! It’s very helpful.
I also decided to give another try for the LISP book I was reading.
October 10th, 2008 at 1:42
Mmm I’m going to have to bookmark this fundamental JS stuff – you’re training me by proxy I’m sure.
I’ve definately got a far better handle on closures now. Thanks.
October 10th, 2008 at 9:46
Nice read, Robert
I must say I already was familiar with most concepts you describe, but it’s good to have them explained again all in one place for quick reference. Especially the infamous loop problem sometimes still bites me in the ass
October 10th, 2008 at 9:48
Great post and good summary of important concepts!
Thanks!
October 10th, 2008 at 11:22
Hi Robert,
I would suggest a better addLinks example, since there is no reason to create two functions, one for the closure, and another for the current link onclick event.
function addLinks () {
for (var onclick = function(num){return function(){alert(num)}}, i=0, link; i<5; i++) {
link = document.createElement(“a”);
link.innerHTML = “Link ” + i;
link.onclick = onclick(i);
document.body.appendChild(link);
}
};
onload = addLinks;
This is more about performances (maniacs) but it is good to understand closure portability, isn’t it?
October 10th, 2008 at 11:47
Thanks guys, I’m glad that you liked it!
Andrea,
Really nice!
I choose my approach partly for easier readability and understanding for everyone, but also honestly because I didn’t think as far as you did.
I think it’s a perfect example of making closures portable! Thanks!
October 10th, 2008 at 13:48
Thanks Robert for a great article! I really need to read up on closures.
October 10th, 2008 at 15:25
Thank you for that article. Made some things clear. But I have one question:
In your addLinks-example, why does link.onclick know that num gets the
value of i and not something else?
It’s not the first time I see this and don’t understand ?-)
October 10th, 2008 at 15:58
Andreas,
Thanks!
Chris,
Thank you!
The key is that the function is self-invoked, i.e. gets executed right away, and sends in the value
ito be the value ofnum.If you examine that part of the code more closely:
link.onclick = function (num) {return function () {
alert(num);
};
}(i);
you can see that it is not just assigned, but actually gets called immediately by having two parentheses at the end, with
iin them.And since inner functions will always have access to their outer/containing functions’ variables (i.e. a closure is created), it will always know that
numis the value ofiwhen it was initially called.I hope it’s clearer now!
October 10th, 2008 at 16:11
It does clarify indeed! What I oversaw was just the parantheses in the end:
}(i);Thanks for explaining and for writing so much good stuff!
October 10th, 2008 at 17:30
Chris,
Thanks!
I’m glad that you understood it!
October 10th, 2008 at 19:43
Thanks for a great article Robert. I also missed the (i) at the end of the onclick function and was wondering how num = i —makes sense now that you pointed it out, though.
I also appreciate you using an example that most of us have problem run into (where i was not what we expected, but instead was the last known value). I think that makes a big difference in helping folks to understand.
October 10th, 2008 at 19:59
Jeff,
Thank you!
Glad that it helped you as well!
October 12th, 2008 at 21:38
[...] Explaining JavaScript scope and closures JavaScript handles scope somewhat differently from other common programming and scripting languages, and it also has an interesting capability for creating and using closures. Robert Nyman explains the concepts clearly. [...]
October 13th, 2008 at 13:16
Thanks for this article.
I’m begining to undertand a little more how works JavaScript.
October 13th, 2008 at 15:17
Great article! This would have saved my ass on a project just a couple of months ago. The closure bit has caused numerous problems for me and most of the solutions I found on the internet were either half-assed or explained nothing, which left me with a viable solution but defenseless for the next time I ran into that problem. Thanks!
Ironically, there are many C or Java programmers that are well educated but use poor form. My C++ professor in college taught us all kinds of bad practices, like using global variables and
system("PAUSE");instead ofcin.ignore();or some other less intrusive object. JavaScript is so much easier to work with if you coming from a strong C++ background where you are mindful of C++’s built-in precautions against scope problems that are essential to OOP, because JavaScript lacks any such thing, being a loosely typed language. It’s easy to fall into sinkholes when beginning with JavaScript.October 13th, 2008 at 20:39
Bleyder,
Great!
Andrew,
Thank you! And absolutely, I can relate how developers coming from C++ or similar can have a hard time with some concepts, so I hope this is helpful for those as well!
October 14th, 2008 at 13:29
[...] reading JavaScript inheritance – how and why and Explaining JavaScript scope and closures, I thought we’d combine the knowledge gained to talk about private, privileged, public and [...]
October 22nd, 2008 at 16:17
[...] reading this article, I strongly recommend reading JavaScript inheritance – how and why and Explaining JavaScript scope and closures first, since many phenomenon below will have their explanation [...]
December 4th, 2008 at 17:09
Cool. I am working on a projec requiring clear mind of how JS module works. It helps a lot.
Thanks
December 16th, 2008 at 13:07
[...] Explaining JavaScript scope and closures Posted in Developing, JavaScript, Technology | Share your thoughts [...]
December 25th, 2008 at 5:59
Thanks for this article, i’m working on a javascript project full of scope issues and closures, very usefull page to keep mind clear
December 25th, 2008 at 23:33
Internet Marketing, Jeff,
Glad that it helped!
December 27th, 2008 at 21:44
[...] Explaining JavaScript scope and closures [...]
February 16th, 2009 at 4:11
[...] http://www.robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ [...]
February 20th, 2009 at 15:33
Thank you so much!
I don’t understand the concept of closure in Javascript until I read your article.
Very useful!
February 20th, 2009 at 18:05
Kevin,
Great to hear that!
March 22nd, 2009 at 18:37
[...] Then we use that id as a name for the function and create a callback that embeds the id of the div the widget will appear in via a closure: [...]
May 8th, 2009 at 14:59
Thanks for a great resource. Your explanation of what is going on in the infamous loop problem was exactly what I needed.
May 8th, 2009 at 16:02
John,
You’re welcome, I’m glad it was helpful!
May 9th, 2009 at 7:41
[...] Object-Oriented Programming Part 1 and Part 2 (a little dated, but explains the basics nicely) Explaining JavaScript scope and closures jQuery for JavaScript programmers Improve your jQuery – 25 excellent tips 5 Tips for Better jQuery [...]
May 23rd, 2009 at 5:32
Sigh finally i grasp the concept behind the closure …
Big thanks…
May 23rd, 2009 at 21:56
slier,
I’m very glad to hear that.
June 18th, 2009 at 23:36
I was wondering why my module wasn’t returning the array — thank you for showing me what i was doing wrong
June 18th, 2009 at 23:40
Skateside,
Glad it was of help!
July 13th, 2009 at 4:14
the best explanation of closures around. I’ve been looking at many articles and this one is just perfect for me. Thanks alot Robert for writing it up
August 14th, 2009 at 17:11
My Only complaint is : Why don’t you have a printer-friendly page of this thing!
Good stuff!
Regards
Vyas,Anirudh
August 17th, 2009 at 0:14
Steve tran,
Thanks, I’m glad you liked it!
Anirudh Vyas,
Well, it could be printed, but I agree – the print-out could definitely look better!
August 18th, 2009 at 15:08
Nice article. This solves my problem
Thanks, Robert.
August 18th, 2009 at 20:23
Shawn,
Glad it was of use to you!
August 24th, 2009 at 19:56
Just Awesome!
I love you man.
Reading your posts for a long time. excellent stuff!
August 24th, 2009 at 20:42
Vsync,
Glad you like it!
August 25th, 2009 at 19:16
Thank you very much for the post, Robert!
As you can see, it’s still a very valuable read even after some months. And being such as it is, I believe it will stay for a long time, for people looking into Javascript a bit deeper than just the newbie stuff…
Your explanation of closures finally cleared the concept for me – I read a couple of them before, but still wasn’t entirely clear about what’s going on – now I can use them wisely
Thanks again and keep up the great blog!
Leo
August 25th, 2009 at 20:19
Leo,
Thank you very much; it sincerely makes me happy to hear it!.
Glad that I made you understand!
August 30th, 2009 at 5:01
Hi Robert
What a great article!!
I’m a newbie coming from a HTML/CCS background and this was the best and clearest explanation of these topics that I’ve found on the web
In the “Infamous Loop” example I have a question:
‘the Incorrect reference states “the onclick event is not being executed”, which I understand, whilst in the Working reference the onclick event appears to be at least evaluated, because the “value is tucked away” ‘
I would appreciate it if you would point out what am I missing
Regards
AlanB
August 30th, 2009 at 20:11
Alan,
Thank you very much!
In regards to the loop, it’s hard to catch the first time, but in the working example the
onclickis assigned a function that is run immediately. If you check, you can see the two parentheses after the function that sends in the value of i, just as it is during that iteration in the loop.That means that the current value of is, indeed tucked away, and later referenced when the element is being clicked.
Hope that made it a little clearer!
August 30th, 2009 at 21:59
Robert
Thank you for your quick response, I now get it!!
I could see where the (i) variable came from but had overlooked the fact that this was a self-invoking function
Thanks again
Alan
August 30th, 2009 at 22:02
Alan,
No problem, glad you understood what I meant!
October 8th, 2009 at 17:59
[...] Explaining JavaScript scope and closures (Robert Nyman) [...]
October 8th, 2009 at 23:31
[...] Explaining JavaScript scope and closures (Robert Nyman) [...]
October 15th, 2009 at 15:42
Hi Robert,
Many thanks for such a succinct article! I’m rather new to all this and it took a bit of time to get my head around self-invoking functions.
If anyone is still struggling, correct me if I’m wrong but for your ‘infamous loop’ problem, if for the sake of argument you call the addLinks function declaration (all the loop and stuff) ‘splurge’, then am I right in thinking that the function call is done immediately by the declaration ‘splurge’(i); ?
I’m curious about several other points as well:
Can you have a self-invoking function without a closure?
If so, would there be any benefit to doing this?
If you use closures, what about memory leeks?
October 16th, 2009 at 10:26
Julie,
Glad you liked it!
About
addLinks: it is rather that within each iteration of the loop, an inner function is called immediately to get a reference to the value ofiat that specific time, and then assign that value to theonclickevent of the link.> Can you have a self-invoking function without a closure?
> If so, would there be any benefit to doing this?
Well, a self-invoking rather creates a closure immediately. Then it is up to you if you want to take advantage of what’s offered with that or not.
> If you use closures, what about memory leeks?
I believe older versions of Internet Explorer had some memory issues with this, but that they should be sorted out by long. Or at least so I hope!
October 16th, 2009 at 15:42
Hi Robert,
Many thanks for the quick reply!
I’ve been playing around with self-invoking functions since your article, and came up with a simple way to “encapsulate” onload, thought you might like to see it
(function()
{
window.onload=init;
})();
This is just like your “dog” function above. But would it technically be a closure though?
Looks like closures give memory leaks to IE before version 8 (good ref is http://msdn.microsoft.com/en-us/library/dd361842(VS.85).aspx ), so they would still effect a substantial number of users right now. But are all closures bad??
October 16th, 2009 at 18:59
Julie,
Nice! However, you are overwriting something on a global object, so it will not allow you to have multiple
window.onload– just thought I’d mention that.And sure, it’s a closure. Whatever you put in there, i.e. that doesn’t explicitly overwrite something that exists outside of it, is only valid and reachable from within that code. If you want to return something to the outside, though, you can use a
returnstatement in that anonymous function, which will be returned globally.Also: no closures are bad; IE is terrible.
But, to my knowledge, Microsoft released some separate script fixes as well. More info can be found in IE Memory Leaks Be-gone and IE’s Memory Leak Fix Greatly Exaggerated.
However, really, don’t worry about this. All major JavaScript libraries, such as jQuery and others, completely rely on closures as well. So, closures is a de-facto approach to efficient JavaScript programming.
October 16th, 2009 at 21:35
Hey Robert,
Thanks for all the tips and and your full explanation about closures. I really get it now! I’ll definitely check out the script fixes. Closures certaiinly look the way to go, especially as you explained above they’re very handy for OOP and encapsulation.
On an aside about onload, good job you pointed that out. I must admit I tend just to pile everything into init and have one onload, not the best way if you have a team working on a project I suppose, but never have any problem with it. I suppose one day I’ll have to catch up with the modern approach…
October 17th, 2009 at 8:36
[...] Explaining JavaScript scope and closures (Robert Nyman) [...]
October 18th, 2009 at 12:16
Julie,
Great! And don’t worry about
onload: one smal step at a time.November 19th, 2009 at 14:49
[...] kapsam ve kaplamlar? anlamak Bu makalenin orijinali (Explaining JavaScript scope and closures) Robert Nyman taraf?ndan kendi blogunda yaz?lm??t?r. Türkçe çevirisi için kendisinden izin [...]
November 30th, 2009 at 18:16
Thanks,Robert.Great article.You help me completely understand the Closure,and this is the first article I read about Self-invoking functions,
though I have learned it from the source code of Prototype.
November 30th, 2009 at 19:21
Mikay,
Glad that you liked it!
January 19th, 2010 at 2:05
[...] Explaining JavaScript scope and closures (Robert Nyman) [...]
January 22nd, 2010 at 22:27
I know this post is a year old, but the section on the loop problem really helped me today. Thanks!
January 25th, 2010 at 9:23
John,
Great to hear!
February 10th, 2010 at 7:18
[...] Closures : Working with closures and Explaining JavaScript scope and closures. [...]
March 17th, 2010 at 1:42
Hey! this post was really helpful!!!
Thx
March 17th, 2010 at 10:54
Jonathan,
Glad you liked it!
March 17th, 2010 at 13:50
[...] Explaining JavaScript scope and closures (Robert Nyman) [...]
March 22nd, 2010 at 19:39
Thank you , this is a clear and concise tutorial.
I tested and modified the code that you are using in your examples.
Here:
function talkDirty () {
saying = “Oh, you little VB lover, you”;
return alert(saying);
}
alert(saying);
as you can see i removed var from the “saying” variable declaration. Now saying becomes global variable. However, when i run the code i keep getting error: that saying is not defined.
I don’t get it . It is a global variable now….
March 22nd, 2010 at 20:11
Maria,
Thanks!
The reason that happens is because on of the trickier aspects of JavaScript. It is best described by Nicholas Zakas, and well worth a read.
April 25th, 2010 at 18:47
This is one of the most helpful articles I have read yet on closures. Thanks!
April 26th, 2010 at 9:53
David,
Thank you!
May 2nd, 2010 at 21:07
????? ??…
Javascript ???…
June 12th, 2010 at 20:15
[...] the loop, we need to add a callback that will do the menu selection. We wrap the handler logic in a Javascript closure so we can access the loop variables [...]
July 13th, 2010 at 3:16
Thanks. Great tutorial. I had some code recently that had the closure issue and didn’t want to work; didn’t understand why until now. Thanks.
Write a comment
Twitter reactions