The way Javascript scopes “var” in loops and how it interacts with closures trips me up every time I go back to writing Javascript code. Here’s a fleshed out example that shows the confusion.
// Demonstrates using closures to capture the value to do what you meant. See also // http://calculist.blogspot.com/2005/12/gotcha-gotcha.html // http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ var data = ["a", "b", "c"]; var wrongFunctions = []; var rightFunctions = []; function load() { console.log("Creating functions"); for (var i = 0; i < 3; i++) { // X will be set to "a", then "b", then "c". But at what scope? var x = data[i]; // The naive way to construction a function that returns X // Will not work: X is scoped to the function load() and // is being modified in the loop var wf = function() { return x }; // A more complicated way to make a function that returns X. // The function execution creates a closure // that captures the value during the loop var rf = function() { var t = x; return function () { return t }; }(); // While the loop is executing and we're building functions, // the output of wf() and rf() will match data[i]. No problem! console.log (" ", x, wf(), rf()); // output is "a a a", "b b b", "c c c". Everything looks great! // Let's store both functions away, what could go wrong? wrongFunctions.push(wf); rightFunctions.push(rf); } } function play() { console.log("Running stored functions"); // Let's loop through and call our stored away functions // and see what happens for (var i = 0; i < 3; i++) { console.log(" ", data[i], wrongFunctions[i](), rightFunctions[i]()); } // output is "a c a", "b c b", "c c c". // wrongFunctions were indeed wrong. } load(); play();