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!
Thanks for explaining JS closures! It's very helpful.
I also decided to give another try for the LISP book I was reading.
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. ๐
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 ๐
Great post and good summary of important concepts!
Thanks!
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? ๐
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!
Thanks Robert for a great article! I really need to read up on closures.
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 ?-)
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 <code>i</code> to be the value of <code>num</code>.
If you examine that part of the code more closely:
<code>link.onclick = function (num) {
return function () {
alert(num);
};
}(i);</code>
you can see that it is not just assigned, but actually gets called immediately by having two parentheses at the end, with <code>i</code> in 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 <code>num</code> is the value of <code>i</code> when it was initially called.
I hope it's clearer now! ๐
It does clarify indeed! What I oversaw was just the parantheses in the end:
<code>}(i);</code>
Thanks for explaining and for writing so much good stuff!
Chris,
Thanks! ๐
I'm glad that you understood it!
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.
Jeff,
Thank you!
Glad that it helped you as well!
[…] 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. […]
Thanks for this article.
I'm begining to undertand a little more how works JavaScript.
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 <code>system("PAUSE");</code> instead of <code>cin.ignore();</code> 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.
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!
[…] 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 […]
[…] 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 […]
Cool. I am working on a projec requiring clear mind of how JS module works. It helps a lot.
Thanks
[…] Explaining JavaScript scope and closures Posted in Developing, JavaScript, Technology | Share your thoughts […]
Thanks for this article, i'm working on a javascript project full of scope issues and closures, very usefull page to keep mind clear ๐
Internet Marketing, Jeff,
Glad that it helped!
[…] Explaining JavaScript scope and closures […]
[…] http://www.robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ […]
Thank you so much!
I don't understand the concept of closure in Javascript until I read your article.
Very useful! ๐
Kevin,
Great to hear that!
[…] 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: […]
Thanks for a great resource. Your explanation of what is going on in the infamous loop problem was exactly what I needed.
John,
You're welcome, I'm glad it was helpful!
[…] 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 […]
Sigh finally i grasp the concept behind the closure …
Big thanks…
slier,
I'm very glad to hear that. ๐
I was wondering why my module wasn't returning the array — thank you for showing me what i was doing wrong ๐
Skateside,
Glad it was of help!
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
My Only complaint is : Why don't you have a printer-friendly page of this thing! ๐
Good stuff!
Regards
Vyas,Anirudh
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!
Nice article. This solves my problem ๐
Thanks, Robert.
Shawn,
Glad it was of use to you! ๐
Just Awesome!
I love you man.
Reading your posts for a long time. excellent stuff!
Vsync,
Glad you like it!
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
Leo,
Thank you very much; it sincerely makes me happy to hear it!.
Glad that I made you understand! ๐
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
Alan,
Thank you very much!
In regards to the loop, it's hard to catch the first time, but in the working example the <code>onclick</code> is 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! ๐
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
Alan,
No problem, glad you understood what I meant! ๐
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
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?
Julie,
Glad you liked it!
About <code>addLinks</code>: it is rather that within each iteration of the loop, an inner function is called immediately to get a reference to the value of <code>i</code> at that specific time, and then assign that value to the <code>onclick</code> event 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! ๐
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(… ), so they would still effect a substantial number of users right now. But are all closures bad??
Julie,
Nice! However, you are overwriting something on a global object, so it will not allow you to have multiple <code>window.onload</code> – 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 <code>return</code> statement 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.
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… ๐
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
Julie,
Great! And don't worry about <code>onload</code>: one smal step at a time. ๐
[…] 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 […]
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.
Mikay,
Glad that you liked it! ๐
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
I know this post is a year old, but the section on the loop problem really helped me today. Thanks!
John,
Great to hear!
[…] Closures : Working with closures and Explaining JavaScript scope and closures. […]
Hey! this post was really helpful!!!
Thx ๐
Jonathan,
Glad you liked it!
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
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.
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….
This is one of the most helpful articles I have read yet on closures. Thanks!
David,
Thank you!
????? ??…
Javascript ???…
[…] 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 […]
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.
Great explanation, and lucid examples. Thank you!
Robert,
Thanks for writing this up – two years later its still helping people (like me!)
– Jack
Greate article. It helps me very much to open my knowledge about javascript programming.
Thanks.
Alex C, Indie, Jack, Tuan Le,
Thank you all, glad it was of use to you!
Nice, thanks
Nice to see that you are still responding after 2 years. I just wanted to say thanks. I have been looking through the voodoo that is jQuery and this article really helped me understand scope and closures. Maybe you can help with this also…
<code>
;(function( scope ){
var Benchmark = scope.Benchmark = function( tests ){
// store the argument { name: test }
this.tests = tests;
</code>
The leading ; is evading my understanding. Also, I do not really understand the second line at all.
Thanks for the great article.
jaj,
You're welcome!
Matthew02,
Not sure about the first semi-colon: it can be about context, and that it's there depending on what's before, or for JavaScript magnification or similar.
The second line is just about assigning several variables/values at the same time.
[…] Then after that you should probably do some reading about scope and closures: http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ Basically you are losing the “scope” of “this” inside your […]
[…] from: ย robertnyman,Douglas […]
[…] http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ […]
[…] Las variables son globales dentro de su contexto (scope). […]
Alternate way to escape the loop iterator problem with retrieve/store using mooTools, or with POJ below:
function addLinks () { //moo
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.store("number",i);
link.innerHTML = "Link " + i;
link.onclick = function () {
alert(this.retrieve("number");
};
document.body.appendChild(link);
}
}
—————-
function addLinks () { // POJ as assoc array
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link["number"] = i;
link.innerHTML = "Link " + i;
link.onclick = function () {
alert(this.number); // or this["number"]
};
document.body.appendChild(link);
}
}
window.onload = addLinks;
^^ Sorry, I know the article is about closures, but if I know anything about beginning JS developers, if they see your solution to the problem, they will always use that solution to the problem – even if the article is context of one issue: closures & scope. Its certainly what i did many, many years ago, but no longer do. Meaning, it may not be the best solution to the problem – but only 1 in context of the article.
Also, be careful if you reference a DOM element in the closure and don’t nullify and then delete the reference. Because of IE garbage collection, you can create a circular reference and pull your hair out trying to find out why there is a memory leak. In an iteration, if you have a dom element that you want to reference later in the extended scope of a closure, be sure test for the object, then at the end of the iteration, nullify and then delete the local reference.
Better yet, instead of adding an anonymous function, add a real function as an event instead, and you won’t have to worry about circular references being created as you add events to DOM elements or even better: add a closure to protect against a circular reference, inside the closure… i know its odd but thats IE.
This may be familiar
https://developer.mozilla.org/en/a_re-introduction_to_javascript
Headcircus,
Thanks for your comments.
First of all, I think it’s vital for developers to understand core JavaScript and not just depend on JavaScript libraries. When they understand the workings of JavaScript, absolutely, but some basic understanding is really desired. Therefore, it is anomy about core JavaScript here.
And sure, there coupled be examples where you call an another, function-external function as well or declare the function in the loop initiation.
Regarding circular references, if I’m not mistaken, is that not something that only applies to IE6 and has been fixed since?
Great article, pal. Solved my problem immidiately.
Thanks for the lesson Robert, you’ve presented and explained this really well.
The Yahoo js pattern is excellent and I’ll definitely be using that a lot!
Cheers!
Balรกzs,
Good to hear!
Emil,
Thanks, glad you like it!
Closures are fine, I learned them from Danny Goodman’s books, but they’re difficult like certain Mathematics concepts. For instance, learning about logarithms, or sorting algorithms is easy, but you can find yourself in an unusual situation where the algorithms you need to use are different from what you may have practiced.
Do you know of any resources more comprehensively studying the concept of closures in JavaScript?
Nice article, btw. ๐
Tom,
Thanks!
Right now I can’t think of anyone that delves much deeper into it – perhaps JavaScript – The Good Parts by Douglas Crockford?
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
Hi! Thanks for the great explanation about javascript scope and closures! I also translated it into russian, which is available here: coders.ask-ru.net/question.aspx?qid2=292
coder,
Nice, thanks!
What a wonderful read, thanks for writing it!
Daniel,
Glad you liked it!
A very nice post for folks like me who know javascript to some extent, and willing to explore more. I’m very sure tht lots of ppl like me wud have gained a world of knowledge on closures.
sridharjay,
Thanks, glad you liked it!
you bloody clever bastard you! nice tut. verrrrrry nice.
theartfuldodger,
Thanks! ๐
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
Is yahoo js code the same as:
var ClassPerson = function () {
// Private
var name = "Robert";
this.getName = function () {return name; },
this.setName = function (newName) {name = newName;}
}
}
var person = new ClassPerson();
alert(person.name); // Undefined
alert(person.getName()); // "Robert"
person.setName("Robert Nyman");
alert(person.getName()); // "Robert Nyman"
Nenad,
You will get the same output, yes. The difference is that you need to instantiate and can’t use the power of prototypes, whereas the Yahoo Module Pattern could be completely anonymous and needs no instantiation (but rather just execution by the parentheses at the end).
[…] Explaining JavaScript scope and closures – Robert's talk (tags: programming javascript web development tutorial) […]
[…] Explaining JavaScript scope and closures – Robert’s talk http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ […]
[…] Las variables son globales dentro de su contexto (scope). […]
[…] http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ This entry was posted on Friday, October 21st, 2011 at 12:07 pmand is filed under web. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. […]
The best article on JavaScript Closures, I ever found on Web. I would say its very very simple and clear.
Keep it up !
The best article on JavaScript Closures, I ever found on Web. I would say its very very simple and clear. Looking forward for more tutorials on JavaScript ๐
Keep it up !
Pawankumar Jajara,
Thank you, glad you liked it!
Goo stuff, I like that.
Congratulations, your explanation saved my life (ok, just my work)..
Thank you so much!
Thanks, glad you liked it!
[…] explanatory code is from the blog post Explaining JavaScript scope and closures LD_AddCustomAttr("AdOpt", "1"); LD_AddCustomAttr("Origin", "other"); […]
Thank you very much for this. ๐
Tom,
Cool, glad you liked it!
Thanks for this article. It’s a nice explanation.
regards
krupar
I think, there ist a mistake. Your Example “Self-invoking functions” returns “German Shepherd” not undefined. (FF5, Chrome 16)
Patrik,
If you check the console in your web browser, you will see that you first get tjhe alert within the function and then an error for the undefined part (i.e., not an alert with the text “undefined”).
Most lucid explanation of closures I’ve found anywhere, and that includes Crockford’s book, “Javascript: The Good Parts”.
Kudos.
Sougata,
Thanks, makes me very happy to hear that!
Hooraah ! never understand the jquery (function()…
Now I can confidently dive into.
And above all nice comments, YOU ARE A TEACHER ! Just in the way you take time to explain and understand even seeming-stupid questions
Yawo,
Thank you, glad you found it useful!
Nice Article … very well explained.
This is very helpful Robert. Thanks a lot for detailed explanation
Ragini, NP,
Thanks, glad you liked it!
[…] Taken from: http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ย This is a great resource and I should refer back to it […]
[…] Explaining JavaScript Scope And Closures […]
Great Article…….Thank you…Thank you very much for explaing about this…………
Suresh,
You’re welcome!
Thank u very much for the post.Really best Practical example I ever came to understand Closures. Keep Posting.
webui,
Glad you liked it!
Excellent explanation, it was very useful to me, specially the loop problem, something overlooked on most closures articles.
thank you
Anderson,
Thank you, glad it was useful!
[…] from it with only one parameter and the other 2 set to specific values you can do this with closures. There are probably other tricks you can do, but I used this one to help troubleshoot one of my […]
thanks man , you created a great article
it’s very useful because of simpleness
There is few more JavaScript confusing bits. ๐ Thanks for the post though.
The only thing I don’t understand here is why you name Modular Pattern as Yahoo JavaScript Module Pattern?? It is not like they created something original right? It is used by many developers and hasn’t been invented by Yahoo.
Marek,
Thanks, glad you liked it!
The pattern – or rather packaging and fame of it – came from Douglas Crockford when he was at Yahoo and got its name from there.
Thanks for this post on closures, now I only have another 97 key JavaScript concepts to go!
Ha ha! Good luck!
[…] already looked at this page and this page, and they sound promising but I just can’t figure out how to make this […]
Just want to thanks for your excellent explain. Really helps me a lot. I’ve translate your work to Traditional Chinese(which use in Taiwan and Hong Kong), mark with your name and have a link to this post. Many tanks again!
taiansu,
Thank you, that’s great!
I’ve added a link to your translation at the top of the article.
“Whoa, whoa! What just happened?” – I laughed out loud when I read that because it was exactly what I was thinking!
Great job explaining it in the end – public and private variables! Is there nothing Javascript can’t do?
Stuart,
๐ Glad you liked it!
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure — an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure — an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure — an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure — an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically aย closureย โ an expression which can work with variables set within a specific context. For […]
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For example: […]
So, the explanation for “The infamous loop problem” seemed to be missing the common programming language I would expect. For a javascript function, the parameters are passed to the function by value, not be reference. In other words, the function gets a “copy” not a “pointer” to the original data.
So, if you don’t do the wrapper function, you get a reference to the exact variable defined in the loop, hence it’s the last value it was assigned.
Might be useful to update the wording, so it’s not quite so confusing as to “why” javascript works that way.
Trenton,
Thanks for the suggestion!
The interesting part there is that, for me, who doesn’t have too much experience with other programming languages, the copy and pointer wording isn’t totally clear.
I’ll think about it. Thanks!
Great job simple and through.
Very good and to the point article. Many thanks!!!
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For […]
thanks… nice explanation…
[…] ?????????????????????????????????????????????????????????????????????????ย – ???????????????????????????????????? […]
great article!
[…] definition on WikiPedia JavaScript Execution Context and Closure Grokking V8 Closures javaScript Scope and Closures Closures and the Module Pattern Closures – Mozilla JS Closures Introduction to Closures […]
great closure example!
Dear Robert,
What is your definition of context as used in your article and how is that different from scope?
-M
If you want to understand closures, walk or run to the following web page:
http://www.javascriptkit.com/javatutors/closures.shtml
It will save you lots of time.
;-))
Just want to say thanks, Robert. I went through quite many tutorials about closures but yours is the easiest to understand.
Thanks everyone who liked the article!
Michael,
In this article, context and scope would refer to the same thing. Context is just more ordinary speak, I’d say. ๐
Also, thanks for the link!
If you say:
1) When the add function is called, it returns a function.
2) That function closes the context and remembers what the parameter x was at exactly that time (i.e. 5 in the code above)
it seems as the closure is created only if we call the function but the closure is created when you define the code:
function add (x) {
.return function (y) {
return x + y;
};
}
so the inner function save in its scope the outer scope of its parent (that’s the lexical scoping rules).
joshua,
Yes, I believe you could say that.
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For […]
Hi Robert,
Really a very good article.
I read same examples before in other articles but with your article i understood them.
It helped me a lot to understand closures.
You explained it in simple words.
Thanx a lot…:)
[…] Blog […]
[…] Closures : Working with closures and Explaining JavaScript scope and closures. […]
Great article, closures became a clearer concept for me thanks to you.
Just a question: as the following code does the same job that your addLinks closure example, could you say which method is the best and why ?
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.id = i;
link.onclick = function() { alert(this.id); }
document.body.appendChild(link);
}
}
window.onload = addLinks;
Dav,
With one, you need to apply a property to the element and reference it, whereas in the closure example, you keep it in memory.
I’d prefer not to clutter the element with something like that, but it’s nothing wrong with it and it works.
[…] will have access to the outer scope even after the outer function is executed. This is basically a closure โ an expression which can work with variables set within a specific context. For […]
Nice demonstration!
About scope, another trick for me…
var a = 4;
function doIt(){
alert(a);
var a = 5;
}
doIt();
Would you explain me why “doIt()” gives an “undefined” a and not the “global ” value of 4?
Many thanks again!
marg,
It’s due to something called variable hoisting, i.e. a gets sent to the top with no defined value. Please read more in JavaScript Scoping and Hoisting.
[…] above 2 snippets are quoted from here. As the author’s explanation, seems the closure makes the […]
This is very clear and concise. I have a much better hold on Scope and Closure.
Thanks Robert!
[…] Explaining JavaScript scope and closures (Robert Nyman) […]
[…] above 2 snippets are quoted from here. As the author’s explanation, seems the closure makes the […]
[…] Podemos tener efectos secundarios que no voy a explicar aquรญ, pero seguro que os parece interesante el artรญculo de Robert Nyman. […]
[…] above 2 snippets are quoted fromย here. As the author’s explanation, seems theย closureย makes the […]
[…] above 2 snippets are quoted from here. As the author’s explanation, seems the closure makes the […]
[…] Nyman ? 2008 ??????? Original Post […]
[…] ???????????????????????????????????????????????????????ย โโ ??????????????????????? […]
Self-invoking functions are in reality IIFE (Immediately-invoked function expression).
There is a significant difference between FD (Function declaration) and FE.
[…] http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ […]
[…] http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ […]
[…] ??????????????????????????????????????????????????????? โโ ??????????????????????? […]
[…] will have access to the outer scope even after the outer function is executed. This is basically aclosureย โ an expression which can work with variables set within a specific context. For […]
very nice .I will suggest this post to my friends .
The only thing I can’t understand .. (and its probably obvious is. ) is “y” argument to “function”
How does it get it value ?
var add5 = add(5);
var no8 = add5(3);
I understand that when add is called with 5 , X gets its value.
when add5 is called with 3 , how does y get it value.
function add (x) {
return function (y) {
return x + y;
};
}
var add5 = add(5);
var no8 = add5(3);
alert(no8); // Returns 8
The result of calling the add function with a value is then saved as a new function that you can call. That means that any value you send in to add5 (e.g. 3) that will be the y value in the function. It’s basically like the x value is hard-coded from before, and the sent in value is the dynamic one, the y one.
Your explanations to closures was perfect and zoned in on my grey area.
thank you!!
Best explanation I’ve read yet about closures. Thanks!
Very nice explanation I have ever read !!! Thanks for posting such a nice article on closuers.
I totally agree with the previously-posted comment, “Most lucid explanation of closures Iโve found anywhere, and that includes Crockfordโs book, Javascript: The Good Parts.”
You are an absolute angel!!
Thanks everyone for the kind words!
var abc = “hello”
function () {
var self = this;
console.log (this.abc);
console.log (self.abc);
function () {
console.log(this.abc);
console.log(self.abc);
}()
}
what will be o/p n why explain me plz
}
In short, the abc variable is global and available everywhere (with or without the this keyword). The self.abc property is only available within that function.
Just for your info, the Traditional Chinese translation link has been updated:
http://blog.taian.su/2012-10-17-explaining-javascript-scope-and-closures-by-robert-nyman/
Thank you for good work!
Nice, thank you!
You’re pretty smart in explaining hard things !! Thank you so much!!
Thanks, glad it was of use!
Close to 7 years since this article but this one gem of an article.Im still in the initial phases as far as concerned but I look forward to posts like these.
Cheers from India
Great to hear, thank you!
Are these two code snippets equivalent (because of hoisting)?
1.)
(function(){
function foo(){
alert(a);
}
var a;
foo();
})();
2.)
(function(){
var a;
function foo(){
alert(a);
}
foo();
})();
Yep.
Hi,
Just wanted to say thank you! You really saved my day. I was looking at the opposite problem today, having created a number of closures that keep the context of the creation time, while I needed them all to use the same reference to the latest state instead. I suspected it had something to do with closure scope and context and your post was the first hit on Google when I started researching.
Thanks!
Thanks, good to hear it was useful!
Wow, awesome post is awesome, even years after it’s first appearance.
This explanation laid ground for a talk I’m going to give for Nodeschool on closures.
Thank you very much!
Thanks! The part about “infamous loop problems” saved the day for me ๐
Scope – can global variable scope be extended between renders. Example:
on initial page render global var x =1
user performs some functions and then clicks on icon.
the icon on click event is x=x + 1. x should be 2. It is 1. Do I have a bug or this not possible?
Best closure article on the web. thank you!!
Thanks, it seems that I have understood it. And I’m a Chinese, my English is not good, but your writing is so concise. My expression may be not accurate, but you know what I want to say is ‘Thanks’.
Still reading in 2016. And still helpful. Thank you man for great explanation. Give this man a cookie…
I have a PHP back-end programming background and I’ve used JavaScript for minor things on the front-end, but now I’m learning how to program in it. I’m reading eloquent javascript and couldn’t grasp closures, so in doing further research before continuing with my reading I came across your page. Your explanation is excellent. Thanks Robert!
Thanks all, glad this is still useful to all of you!
Thanks for useful information. Keep continue to share more!
Hey Robert,
Thanks for the article!!
I do have a question though. Turns out that I’ve been looking at closures lately because someone asked me about broken code that doesn’t uses closures (besides the infamous loop example, which can also be considered using a list), and I’m having a lot of troubles coming up with something. I’ve been looking around for bad closures in JS but with no luck. Seems that everyone kinds of forget about the problem once it gets solved, I know I have ๐
Do you know any other snippets that shows issues because closures are not created?
Thanks,
Rodrigo.