TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

How do JavaScript closures work?

81 pointsby abrahamalmost 14 years ago

12 comments

aufreak3almost 14 years ago
For a mental model, pretend that variables are referring to storage locations in an array and you reference them using indices - v = [..., v[100], v[101], v[102], v[103], ....]<p>For example, take the function in the stackoverflow answer -<p><pre><code> function foo(x) { var tmp = 3; return function (y) { alert(x + y + (++tmp)); } } </code></pre> When you make a call to foo(10), pretend that the bound variables in the body of the function get assigned sequence numbers starting from 100 -<p><pre><code> function foo() { v[100] = 10; // x = 10 v[101] = 3; // var tmp = 3; return function (y) { alert(v[100] + y + (++(v[101]))); } } </code></pre> So you get as the result,<p><pre><code> function (y) { alert(v[100] + y + (++(v[101]))); } </code></pre> 'y' remains as such because it hasn't been bound to a value just yet. That will happen only when you <i>call</i> this result function.<p>Now, when you call foo another time like foo(20), the sequence continues from 102 ...<p><pre><code> function foo() { v[102] = 20; // x = 20 v[103] = 3; // var tmp = 3; return function (y) { alert(v[102] + y + (++(v[103]))); } } </code></pre> So you get <i>another</i> function as the result -<p><pre><code> function (y) { alert(v[102] + y + (++(v[103]))); } </code></pre> The store now reads v[100] = 10, v[101] = 3, v[102] = 20 and v[103] = 3.<p>It becomes clear what the two result functions do. Note that they do not share the same storage locations and therefore the two ++ calls increment <i>different</i> storage locations.<p>In this model, each "var" statement and each argument of a function causes the index assigned to be incremented on a function call, and unbound variables do not cause increments. The behaviour of closures created in javascript is as though such an indefinitely increasing numbering scheme is being used under the hood.<p>(edited a bit for clarity).
评论 #2689136 未加载
raganwaldalmost 14 years ago
Let's make closures easy:<p><a href="https://github.com/raganwald/homoiconic/blob/master/2010/10/let.md#readme" rel="nofollow">https://github.com/raganwald/homoiconic/blob/master/2010/10/...</a>
评论 #2688618 未加载
csomaralmost 14 years ago
For those who wonder how useful JavaScript closures can be. They are very useful. Take a simple pattern. You are iterating through a statement, and you want to use the variable <i>i</i> of the statement in another function.<p><pre><code> for (var i = 0; i &#60; 5; i++) { console.info(i); } </code></pre> This works fine. And the console displays 1, 2, 3 and 4. But let's suppose that you have the following code:<p><pre><code> for (var i = 0; i &#60; 5; i++) { $(DOMelement:eq(i)).click(function() { console.info(i); }); } </code></pre> The console will always display "4" whichever DOMelement you clicked. Surprise? That's because it calls <i>i</i> which holds 4. JavaScript passed the argument by reference to i and by the time you clicked, the iterations already finished.<p>JavaScript closures help solve this problem (Luckily). Here is how:<p><pre><code> for (var i = 0; i &#60; 5; i++) { $(DOMelement:eq(i)).click(function() { return function() { console.info(i); } }); } </code></pre> That's because JavaScript returns now a new function for each DOM element. Each new function holds the <i>i</i> value while iteration and now the final value.
评论 #2688339 未加载
seliopoualmost 14 years ago
If you _really_ want to know how JavaScript closures work:<p><a href="https://github.com/brownplt/LambdaJS" rel="nofollow">https://github.com/brownplt/LambdaJS</a>
skrebbelalmost 14 years ago
A closure is the hotel room key that you kept so you could always access all items you hid in there, and the hotel personnel cooperating with the whole ordeal.
anc2020almost 14 years ago
Hi, I wrote the accepted answer and welcome changes or suggestions (it's community wiki).
reichsteinalmost 14 years ago
Javascript closures are more fun than most other languages, because the scope chain can be changed after the closure has been created. Try explaining this to a 6-year old:<p>function foo(o) { eval("var x = 10;"); with (o) { return function(e) { if (typeof e == "string") eval(e); return x; } } } this.x = 42; var f = foo({x : 37}); alert(f("var x = 13")); alert(f()); alert(f("delete x")); alert(f("delete x"));<p>Each call returns a different variable called "x".
euroclydonalmost 14 years ago
Could be expanded further to describe when generating multiple functions, each with a reference to an object is a useful design pattern in JavaScript, and when it's a common mistake.
评论 #2688671 未加载
dkastneralmost 14 years ago
I've found that using function compositions/closures for event handling makes my JS code much more testable and readable: <a href="http://numbers.brighterplanet.com/2011/06/10/a-pattern-for-javascript-events/" rel="nofollow">http://numbers.brighterplanet.com/2011/06/10/a-pattern-for-j...</a>
jberrymanalmost 14 years ago
If we learned to program in lisp, scheme, haskell, or some other language with (dare i say?) sane semantics we'd be wondering what all the fuss about closures was:<p><a href="http://www.haskell.org/haskellwiki/Closure" rel="nofollow">http://www.haskell.org/haskellwiki/Closure</a>
stanleydrewalmost 14 years ago
This explanation is the most thorough I've found. It also happens to be the first Google result for "javascript closures".<p><a href="http://jibbering.com/faq/notes/closures/" rel="nofollow">http://jibbering.com/faq/notes/closures/</a>
ptioalmost 14 years ago
I like how Douglas Crockford explained it here: <a href="http://www.youtube.com/watch?v=hQVTIJBZook#t=27m20s" rel="nofollow">http://www.youtube.com/watch?v=hQVTIJBZook#t=27m20s</a>