3

I have the below function which always results me 5. I see that the function inner is getting executed in the global context, so the result is 5 always.

I tried to wrap the entire loop inside a closure, so that it creates a new scope yet it failed.

var myAlerts = [];

for (var i = 0; i < 5; i++) {
    myAlerts.push(
        function inner() {
            alert(i);
        }
    );
}

myAlerts[0](); // 5
myAlerts[1](); // 5
myAlerts[2](); // 5
myAlerts[3](); // 5
myAlerts[4](); // 5

Can anyone tell me on how to fix this scoping issue here?

Shane
  • 5,517
  • 15
  • 49
  • 79
  • 1
    on a side note its a bad idea to define a function within a loop. It means function has to be created for each loop – Craicerjack May 23 '15 at 23:51
  • Whats happening in your code is that you are pushing the function `inner()` to your array. So for each step in your loop you push a function called `inner()` that takes a value `i` to the array. The problem here is that when you access the values you are calling that function `inner()` and passing it the value `i`. Given that that last value of i in your code was 5, you are therefore calling `inner(5)` for each item in `myAlerts`. – Craicerjack May 24 '15 at 00:00

2 Answers2

3

Try closures:

for (var i = 0; i < 5; i++) {
    (function(i){
      myAlerts.push(
        function inner() {
            alert(i);
        }
      );
    })(i);
}
1

Wrapping the function in a closure works:

var myAlerts = [];

for (var i = 0; i < 5; i++) {
  myAlerts.push((function(i) {
    return function inner() {
      alert(i);
    }
  })(i));
}
tomasbasham
  • 1,695
  • 2
  • 18
  • 37