You have been referred to this item:

Closures

There are times when you need to save off a reference to a function and call it later. Some common examples are assigning event handlers and setting timers.

One thing you must keep in mind when saving off function references for later execution is that any variables that exist in such functions will be evaluated at execution time, not at creation time. Observe:

function setListeners(elements) {
    for (var i=0;i<elements.length;i++) {
        elements[i].onclick=function () { alert(i); };
    }
}

Some would expect each element to output 'i' at the time of the iteration. However, try it yourself and see the real result:

You see how both buttons output the same value -- the last value of 'i' at the time setListeners finished executing. This can cause problems if you are not aware of this behavior and there is a general solution for saving off a reference to a function whose variables should take on values that exist at creation time rather than execution time.

Enter getRef()

The way to accomplish the desired result is by creating a closure around our function in question. Notice that our anonymous function is still the same, just wrapped in getRef(). Like so:

function getRef(i) {
    return function () { alert(i); };
}

function setListeners(elements) {
    for (var i=0;i<elements.length;i++) {
        elements[i].onclick=getRef(i);
    }
}

Notice that each button now displays the value at the time of iteration.

This same method can be applied to any number of other situations where this "save off and fire later" method is used.

Warning

Using closures often creates situations in which some browsers cannot release memory when the page unloads, which results in a "leak" between pages in a browsing session.

A solution without getRef()

Sometimes, instead of wrapping the variable inside a closure inside a function, and having to create the getRef() function to begin with, there is a lighter alternative, both in terms of performance and memory optimization. Simply assign the variable you want preserved as a property of the object and refer to the property instead of the variable.

function setListeners(elements) {
    for (var i=0;i<elements.length;i++) {
        elements[i].idx=i;
        elements[i].onclick=function () { alert(this.idx); };
    }
}

Reminder: The stored property will show up in for (var in obj) loops.

See also

Jim Ley's Closures Article