In fact, it is a closure, and it works very much like closures in Ruby and
other languages.

Keep in mind that a JavaScript object is reference counted and remains in
existence as long as there are any references to the object. Once there are
no more references to an object, it becomes available for garbage
collection.

When you call a function, JavaScript creates a private object for that
particular call of the function. This object has properties for the
function's local variables and arguments. The object is not directly
accessible from JavaScript code, but it obeys the same garbage collection
rules as any other JavaScript object.

The function call object has one reference added when the function is
entered, and that reference is removed when the function exits. So, in the
typical case where there are no other references to the function call
object, it becomes available for garbage collection at that point.

However, if any other code holds onto a reference to the function call
object, then the object cannot be garbage collected until all of those
references are removed. Similarly, if you hold a reference to any of the
function's arguments or variables, that is also a reference to the function
call object. So as long as there are any references to the function call
object, all of that function's arguments and local variables are kept
around.

In the code I posted, the $(...).click(...) call creates a reference to the
inner anonymous function. That function in turn contains a reference to the
"i" variable in the outer function (the "clicker" function). So as long as
the click handler exists that reference to the outer function's function
call object will also exist. Therefore, all of the arguments and local
variables for that function call remain in existence.

Someone may be able to explain this better, but that's the general idea.

For more info, here are a couple of articles on JavaScript closures:

http://www.jibbering.com/faq/faq_notes/closures.html

http://blog.morrisjohns.com/javascript_closures_for_dummies

-Mike

> From: Rabbit
> 
> Hmm... I didn't realize this until I was falling asleep last 
> night, but what you've demonstrated is similar to a closure 
> in Ruby, except not. My understanding of what you said is 
> something along the lines of...
> 
> An argument to a method becomes a local variable in that 
> method and is _retained_. But, how? I get the feeling that 
> when you pass an argument to a method the argument "gets 
> stashed away for later," but how is it that the correct value 
> is recalled?
> 
> In other words, the code you presented works (I tested it), 
> and I understand that it does, but I don't understand how or why.
> 
> Can anyone shed some light on this?
> 
> - Daniel
> 
> ---
> 
> On Dec 22, 12:55 am, "Michael Geary" <[EMAIL PROTECTED]> wrote:
> > As an alternative to the other solution you posted, here is how you 
> > can do it with code more like the code below:
> >
> > for(var i = 0; i < 30; i++)
> >   clicker( i );
> >
> > function clicker( i ) {
> >   jQuery('#day_' + i).click(function() {
> >     console.log('i is ' + i);
> >     jQuery('#day_' + i + '_modal').jqmShow();
> >   });
> >
> > }
> >
> > As you can see, all I changed was to put your code inside a 
> function 
> > and call that function 30 times.
> >
> > Why did your original code show "i is 30" for each element? Because 
> > there is only a single variable "i", and when you call console.log 
> > it's using the current value of "i" - not the value that "i" had at 
> > the time you added the click event.
> >
> > By moving this code into a function, a new variable "i" is created 
> > each time the function is called. You no longer have all the code 
> > sharing a single variable - each instance of the function 
> gets its own.
> >
> > -Mike
> >
> > > From: Rabbit
> >
> > > The following code:
> >
> > > for(var i = 0; i < 30; i++) {
> > >   jQuery('#day_' + i).click(function() {
> > >     console.log('i is ' + i);
> > >     jQuery('#day_' + i + '_modal').jqmShow();
> > >   });
> > > }
> >
> > > Runs, but always reports "i is 30".
> >
> > > Now, I understand why it does that, but why doesn't the jqmShow 
> > > method work? It appears as though the code that "gets 
> executed" is 
> > > dynamic.
> > > In other words, when the click event occurs JavaScript 
> looks up the 
> > > code as it was at the end of its execution, when variable 
> i is 30, 
> > > instead of "remembering" that at one point it was something else.
> >
> > > Did that make sense?
> >
> > > Any ideas how to get around this without typing in all 30 click 
> > > events?
> 

Reply via email to