Javascript closures gotcha with loop variables

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();