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

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top