Deal of the Day

Home » Main » Manning Forums » 2008 » Secrets of the JavaScript Ninja

Thread: Loopy Loops: Listing 3-20

Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 6 - Pages: 1 - Last Post: May 4, 2008 4:50 AM by: room51
room51

Posts: 34
From: Nottingham, UK
Registered: 4/30/08
Loopy Loops: Listing 3-20
Posted: May 1, 2008 3:58 PM
  Click to reply to this thread Reply

Are you actually being vindictive or am I just too timid?

In listing 3-20 you use the variable i throughout. Is this common practice, recommended or necessary? Your listing has: (i changed to j)


for ( var j = 0; j < div.length; j++ ) (function(j){
div[j].addEventListener("click", function(){
alert( "div #" + j + " was clicked." );
}, false);
})(j);


Or, is the i in the looped function just a dummy variable? How would changing it affect the readability of the listing?


for ( var i = 0; i < div.length; i++ ) (function(n){
div[n].addEventListener("click", function(){
alert( "div #" + n + " was clicked." );
}, false);
})(i);


jeresig

Posts: 13
From: Boston, MA
Registered: 5/1/08
Re: Loopy Loops: Listing 3-20
Posted: May 1, 2008 4:26 PM   in response to: room51 in response to: room51
  Click to reply to this thread Reply

That was done intentionally - there's no reason to have two variables with two names that represent the same thing. Keeping the names identical keeps their intent identical as well (you don't have to think "oh, I'm looping with i but I call it n inside here").

room51

Posts: 34
From: Nottingham, UK
Registered: 4/30/08
Re: Loopy Loops: Listing 3-20
Posted: May 1, 2008 4:33 PM   in response to: room51 in response to: room51
  Click to reply to this thread Reply

Okay, excellent. That makes good sense.

I think my niggling confusion was coming from the fact that the chapter is about closures. Without the executed anonymous function, the event listener had a closure which had i = 2. With the inner function we have a new closure using the i argument of the function, although the original closure is still there with i = 2.

Does that make any sense?

room51

Posts: 34
From: Nottingham, UK
Registered: 4/30/08
Re: Loopy Loops: Listing 3-20
Posted: May 1, 2008 4:41 PM   in response to: room51 in response to: room51
  Click to reply to this thread Reply

Ah!

The original closure isn't there. Which is the point of executing the inner function. And, so, using i all the way through makes perfect sense.

Thanks.

room51

Posts: 34
From: Nottingham, UK
Registered: 4/30/08
Re: Loopy Loops: Listing 3-20
Posted: May 2, 2008 2:40 PM   in response to: room51 in response to: room51
  Click to reply to this thread Reply

Trying to get my head around these ideas, I've created some examples which I think follow on accurately from the text.
http://www.room51.co.uk/js/closures.html

jeresig

Posts: 13
From: Boston, MA
Registered: 5/1/08
Re: Loopy Loops: Listing 3-20
Posted: May 2, 2008 2:53 PM   in response to: room51 in response to: room51
  Click to reply to this thread Reply

That looks real good! I'd offer an alternative to the last one:

(function() {
for (var i = 1; i < 4; i++) (function(i){
document.getElementById("btn5_" + i).onclick = function() {alert(i)};
})(i);
})();

It's, debatably, easier to understand. For me it is, at least. By adding in the extra anonymous function around the loop itself I can be confident that the closure state of everything inside of it will be maintained properly (rather than having to handle each closure individually).

room51

Posts: 34
From: Nottingham, UK
Registered: 4/30/08
Re: Loopy Loops: Listing 3-20
Posted: May 3, 2008 2:15 AM   in response to: jeresig in response to: jeresig
  Click to reply to this thread Reply

Great! I had to think about it for a while and having slept on it I think I understand the changes.

* The i for the button id and the alert are both together inside the same inner function.
* The button id uses the i parameter immediately.
* The alert maintains a reference to the i parameter via a closure.

This seems similar to my example apart from
* The loop i is passed into the function to set the button id rather than setting the id directly.
* There is no need to return a function from a function to set the handler.

I've attributed the example to you on my example page. I hope that's okay.

For reference, here's my version

(function() {
for (var i = 1; i < 4; i++) {
document.getElementById("btn5_" + i).onclick = function(i) {
return function() {alert(i)};
}(i);
};
})();


Legend
Gold: 300 + pts
Silver: 100 - 299 pts
Bronze: 25 - 99 pts
Manning Author
Manning Staff