js2015 js2015 - 2 months ago 7
Javascript Question

Why can't I pass in a parameter to function in a for loop

Trying to pass

i
into the closure to make it local to avoid the closure issue of
i
remaining at 2.

var myFunctions = {};

for (var i = 0; i < 3; i++) { // let's create 3 functions

myFunctions[i] = function(i) { // and store them in myFunctions
console.log("My value: " + i); // each should log its value.
};

}

for (var j = 0; j < 3; j++) {
myFunctions[j](); // and now let's run each one to see
}

// > "My value: undefined
// > "My value: undefined
// > "My value: undefined

Answer

The reason that's happening is because you've got i as a parameter of the functions, but then you don't pass a value.

There are three ways to fix this.


First, you can pass the value as a function parameter:

myFunctions[j](j);

The second way would be to use a function closure to store the value:

var myFunctions = {}

function generateValuePrintout (value) {
    return function () {
        console.log("My value: " + value);
    };
}

for (var i = 0; i < 3; i++) {
    myFunctions[i] = generateValuePrintout(i);
}

for (var j = 0; j < 3; j++) {
    myFunctions[j]();
}

This is a cleaner way to do it than the first because it means you don't need to pass any value into the function for it to know about its closure.


The last way (my favourite) would be to store the value for the function using let (so that it is scoped correctly), and then call it without a parameter (remove the parameter from the function definition also):

for (var i = 0; i < 3; i++) {      // let's create 3 functions

    let closureValue = i;

    myFunctions[i] = function() {  // and store them in myFunctions
        console.log("My value: " + closureValue); // each should log its value.
    };

}
for (var j = 0; j < 3; j++) {
    myFunctions[j]();              // and now let's run each one to see
}

The output of each will be:

My value: 0

My value: 1

My value: 2