AndyB
AndyB

Reputation: 391

javascript closure in loop

Following code is given:

var a = [ ], i = 0, j = 0;

for (i = 0; i < 5; i += 1) { 

  (function(c) {
    a.push(function () { 

    console.log(c); });

  })(i);
};

for (j = 0; j < 5; j += 1) { a[j](); } 

Why does i always get bigger by 1 instead of staying 5? Hasn't the foor loop already been passed, so the i parameter given to the anonymous function should be 5?

Upvotes: 0

Views: 76

Answers (2)

jfriend00
jfriend00

Reputation: 707148

chhowie's answer is absolutely right (and I upvoted it), but I wanted to show you one more thing to help understand it. Your inner function works similarly to a more explicit function call like this:

var a = [ ], i = 0, j = 0;

function pushFunc(array, c) {
    array.push(function () { 
        console.log(c); 
    });
}

for (i = 0; i < 5; i += 1) { 
    pushFunc(array, i);
}

for (j = 0; j < 5; j += 1) { a[j](); } 

Which should also help you understand how c comes from the function argument, not from the for loop. Your inner function is doing exactly the same thing as this, just without an externally declared named function.

Upvotes: 2

cdhowie
cdhowie

Reputation: 168948

If you referenced i from the inner closure then yes, you would see the result being 5 in all cases. However, you pass i by value to the outer function, which is accepted as parameter c. The value of c is then fixed to whatever i was at the moment you created the inner closure.

Consider changing the log statement:

console.log("c:" + c + " i:" + i);

You should see c going from 0 to 4 (inclusive) and i being 5 in all cases.

Upvotes: 3

Related Questions