View Full Version : pass arg to function by value.

07-24-2009, 05:39 AM
ok I have a unique problem, I need to pass a variable's value to a function instead of a pointer (reference) to the variable as by the time the function is called (because of the SetTimeout function) the variables value has changed.

I realise that may not be so clear so I've included the long explanation below, please bare with me ... =p

I have a 2 dimensional menu, when you hover over menu item it animates. to exaggerate that it is a menu (from the design it's not immediatly apparent) I decided to add a simple animation for when the page loads where it loops through each menu item and animates it in sequence.

each of the sub menu items are stored in a 2D array (SubMenuItemsArray) and I get the "wave" effect by having a short (60 millisecond) pause between each animation (achieved with Window.SetTimeout).

heres the code, I've set i and j to 0 after the loop to highlight the issue.

for(var i = 0; i < SubMenuItemsArray.length; i++)

for(var j = 0; j < SubMenuItemsArray[i].length; j++)


animateSubMenuItem( SubMenuItemsArray[i][j]);
}, (j*60));
i = 0;
j = 0;

now, the issue, by the time SetTimeout runs the animation code i and j have already been set to 0. And it therefore calls:

animateSubMenuItem( SubMenuItemsArray[0][0]);
20 times, animating the first sub menu item ... 20 times and none of the others.

this happens because the function isn't called until (j * 60) milliseconds have passed and i and j are passed to the function by reference, whereas I need to pass only the value of i and j if the function is to work.

is there a way to do that? or a simple work around that anyone can think of? I'm working on a work around but at the moment it isn't too elegant =p.

Thanks for any help

07-24-2009, 06:29 AM
not entirely sure why, (i'm not complaining) but putting quotes around everything and removing the function part seems to make it work (not entirely sure of the difference it makes, I thaught the two ways of writing it were one and the same)

this is the corrected code:

setTimeout("animateSubMenuItem( SubMenuItemsArray[" + i + "][" + j + "])", (j*60));

sorry for the clutter,

07-24-2009, 07:34 AM
I personally highly dislike using strings when you can do without them.

for (var i = 0; i < SubMenuItemsArray.length; i++) {
for (var j = 0; j < SubMenuItemsArray[i].length; j++) {
setTimeout ((function (i, j) {
return function () {
animateSubMenuItem (SubMenuItemsArray[i][j]);
}) (i, j), j * 60);

rnd me
07-24-2009, 08:42 AM
i prefer [].map to loops:

row.map(function(cell, n){
animateSubMenuItem( cell );
}, n * 60 );


To me, it looks cleaner.
Array.map also lets you re-use loop code elsewhere and avoids the problem encountered by the OP by providing a private scope that loops just don't have.

well not yet anyway, though i am working on a library that provides block and loop scope...