closure problem

J

jman

for ( var i = 0; i < div.firstChild.childNodes.length; ++i )
{
var marker = new Object();
marker.iii = i;

sys.addListener( marker, "click", function()
{
alert(marker.iii);
});
}

looks like when clicked - marker object has the value of the last
object thru the loop.

i'd like it to display the appropriate iii value.
 
N

Nick Fletcher

for ( var i = 0; i < div.firstChild.childNodes.length; ++i )
{
var marker = new Object();
marker.iii = i;

sys.addListener( marker, "click", function()
{
alert(marker.iii);
});
}

looks like when clicked - marker object has the value of the last
object thru the loop.

i'd like it to display the appropriate iii value.

JavaScript has function level scoping as opposed to block level (like
other languages). Your marker object is visible across iterations and
the closure will always reference the last instance of the marker
object. I believe you could stop this from happening using a self-
executing anonymous function, like so:

for ( var i = 0; i < div.firstChild.childNodes.length; ++i )
{
(function() {
var marker = new Object();
marker.iii = i;

sys.addListener( marker, "click", function()
{
alert(marker.iii);
});
})(); /* These brackets are necessary to execute the anonymous
function */
}

This should scope the marker inside the anonymous function and the
closure should behave the way you want.
 
T

Thomas 'PointedEars' Lahn

Nick Fletcher wrote/zu Deiner Priorität-Alpha-1-Nachricht von Sternzeit
06.03.2008 18:16:
JavaScript has function level scoping as opposed to block level (like
other languages).

JFYI: Since version 1.7 it also has block scoping, but you need to declare
that version as it introduces new keywords.

http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Block_scope_with_let
Your marker object is visible across iterations and
the closure will always reference the last instance of the marker
object. I believe you could stop this from happening using a self-
executing anonymous function, like so:

for ( var i = 0; i < div.firstChild.childNodes.length; ++i )
{
(function() {
var marker = new Object();
marker.iii = i;

sys.addListener( marker, "click", function()
{
alert(marker.iii);
});
})(); /* These brackets are necessary to execute the anonymous
function */
}

This should scope the marker inside the anonymous function and the
closure should behave the way you want.

You create an additional closure of `i' needlessly. It is overkill
and the base code is still very inefficient and error-prone.

Consider this instead:

for (var i = 0, len = div.firstChild.childNodes.length; i < len; ++i)
{
var marker = new Object();
marker.iii = i;

sys.addListener(
marker, "click",
(function(me) {
return function() {
window.alert(me.iii);
};
})(marker)
);
}


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Closure bug 67
How to remove the undefined thing? 1
Closure 3
Changing the content in the infoWindow from text to pie char 0
Namespace problem 2
Filename undefined for Blob ? 1
Point Locate 0
Closure scope confusion 14

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top