1

I've taken a bit of code from How do JavaScript closures work?

I understand how closure works here:

function foo(x) {
  var tmp = 3;
  function bar(y) {
    alert(x + y + (++tmp)); // will alert 16
  }
  bar(10);
}
foo(2);

This will always alert 16, because bar can access the x which was defined as an argument to foo, and it can also access tmp from foo.

What I don't understand is how it works here:

function createArray(array){
    var outPut = [];
    for (var i = 0; i<array.length; i++){
        var inPut = array[i];
        outPut.push( function() {alert(inPut + " " + array[i])} ); 
    }
    return outPut;
}

function tryArray(){
    var finishedArray = createArray([1, 2, 3, 4]);    
    for (var i = 0; i < finishedArray.length; i++) {
        finishedArray[i]();
    }

}

tryArray();

It logs 4 undifined four times.

What I expected to happen was it to log. 1 1 2 2 3 3 4 4

Why didn't this happen???

Community
  • 1
  • 1
Zachooz
  • 535
  • 1
  • 12
  • 25
  • 2
    Did you read [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example?rq=1)? – p.s.w.g Jul 16 '14 at 20:02
  • The "i" in those functions built in the "createArrays" function refer to the "i" in "createArrays", not the "i" in "tryArray". JavaScript is lexically scoped, which means that what matters is where in the code a function was created, not where it's called. – Pointy Jul 16 '14 at 20:04
  • @Pointy I don't think that's his confusion. It's the usual misunderstanding about the way a closure captures the iteration variable around the closure, the `i` in `createArray`. – Barmar Jul 16 '14 at 20:05
  • @p.s.w.g Yes! That's what is confusing me. But I didn't really get what Harto meant by 'Well, the problem is that the variable i, within each of your anonymous functions, is bound to the same variable outside of the function.' – Zachooz Jul 16 '14 at 20:11
  • @Barmar, I don't know if this question should've been closed because he's got a unique gotcha with the undefined. Anyways the reason you got 4 was because INSIDE the loop the last value of i was 3, which got the value of 4 from the array. However `i` still gets incremented one more time to 4, and then fails the `i < length` test and exits the loop. so array[i] == undefined because at that point i is now 4. – Daniel Gimenez Jul 16 '14 at 20:11
  • @DanielGimenez I'm a bit confused. You are saying the last value of i was 3 but then you say that gets incremented one more time so shouldn't the last value be 4? -- undefined undefined vs. 4 undefined – Zachooz Jul 16 '14 at 20:21
  • @Zachooz `i` gets incremented to 4, but `inPut` retains it's old value (which was `array[3]`) because it doesn't enter that loop again. So you'd expect that `inPut != array[4]`. – p.s.w.g Jul 16 '14 at 20:26
  • 1
    @p.s.w.g I think I understand now. When the for loop ends - `input = array[3]` however i gets incremented one more time. This means when the functions in the `finishedArray[]` are called it alerts `input` whose last value was `array[3]` and `array[4]` because the last value of `i` was 4 – Zachooz Jul 16 '14 at 20:41
  • @Zachooz That's it exactly. :) – p.s.w.g Jul 16 '14 at 20:43

0 Answers0