appsunited
appsunited

Reputation: 1667

JS Scope & Closure Headache

See the code, which explains more than 1000 words. I don't get it, why all 5 created functions always return 5 (last iteration value). I am really interested, what's wrong or what I have missed. I remember dare, Douglas Crockford has talked about this thing, but I didn't find that resource either.

function createFunctions(n) {
    var arrayFunctions = [];

    for (var i=0; i<n; i++) {
        arrayFunctions.push(function() {
            console.log(i);
        });
    }

    return arrayFunctions;
}

var arrayFunctions = createFunctions(5);

arrayFunctions[2]();  // returns 5 instead of 2
arrayFunctions[3]();  // returns 5 instead of 3
arrayFunctions[4]();  // returns 5 instead of 4

Upvotes: 0

Views: 64

Answers (3)

ssawchenko
ssawchenko

Reputation: 1228

Not sure if it is the best way, but you could create a function that returns a function which stores the correctly scoped variable:

function createFunctions(n) {
    var arrayFunctions = [];
    for (var i=0; i<n; i++) {
        var scopedFunction = function(scopedI) {
            return function() {
                 console.log(scopedI);
            }
        }
        arrayFunctions.push(scopedFunction(i));
    }

    return arrayFunctions;
}

I tested this out in jsfiddle and it appears to give the intended result.

Upvotes: 0

Sean
Sean

Reputation: 4470

The functions are closing over the variable, not the value of the variable. This means that they all refer to the i that is defined in the loop and is updating at every iteration. By the time createFunctions returns the loop has completed and i is at its final value (5).

function createFunctions(n) {
    var arrayFunctions = [];

    for (var i=0; i<n; i++) { 
        (function(j) {
            arrayFunctions.push(function() {
                console.log(j);
            });
        }(i));
    }

    return arrayFunctions;
}

Upvotes: 3

Daniel A. White
Daniel A. White

Reputation: 190905

It is because the functions are holding onto the reference of i, not the value of i.

Upvotes: 1

Related Questions