-2

Possible Duplicate:
Closures in a for loop and lexical environment

I am learning Closures in JavaScript... I saw example of simple code :

for (var i = 0; i < 10; i++) {
  document.getElementById('box' + i).onclick = function() {
    alert('You clicked on box #' + i);
  };
}

But what exactly happens is that no matter what div you select you get an alert about the last i - last iteretion.

I saw an solution to that problem with inner function, but why is this happens? doest it's not binding the onclick event on every iteretion?

Community
  • 1
  • 1
Alex Opent
  • 111
  • 1
  • 13
  • Search for `[javascript] callback loop last value`. No shortage of duplicates. –  Dec 24 '12 at 05:31
  • -1 because, since you *know* about closures, this would have been easy to find a duplicate for. Try using the search feature or look at the "similar questions" when creating a post. –  Dec 24 '12 at 05:33

2 Answers2

1

Each iteration creates a new function, but each function references the same variable i (a location in memory). The value of i is only evaluated at the time when a handler is executed. That moment is long after the for loop finished and at that time, i has the value 10.

Wikipedia's article about closures is worth a read and mentions the two ways closures could work: Either by binding the current value of the variable or a reference to the variable itself. The latter is the case with JavaScript.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • That last paragraph is slightly misleading in context. For instance, in both Scala and C# a closure also "binds a reference to the variable". The difference is the scope of a [particular] variable. –  Dec 24 '12 at 06:05
  • Mmmh, I might have oversimplified a bit but I think it helps to understand the differences, no? – Felix Kling Dec 24 '12 at 06:11
  • I'm not saying it's incorrect - and the answer still has my up-vote. It's just a note/nit for future readers. –  Dec 24 '12 at 06:13
0

Good old same-variable issue. You can easily circumvent it by passing it through a self-calling function taking i as a parameter:

for(var i = 0; i < 10; i++) {
    (function(i) {
        document.getElementById('box' + i).onclick = function() {
            alert('You clicked on box #' + i);
        };
    })(i);
}

The reason why this is necessary and works is that i is usually always the same - JavaScript only has a function scope. By using the self-calling function that takes i as a parameter you create a new i everytime which will be then saved within the closure of the callback function.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636