0

This very good Stack Overflow answer gives an example of how closures can work counter intuitively when returning anonymous functions within a list.

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) {
        var item = 'item' + i;
        result.push( function() {alert(item + ' ' + list[i])} );
    }
    return result;
}

function testList() {
    var fnlist = buildList([1,2,3]);
    // Using j only to help prevent confusion -- could use i.
    for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
    }
}

This code will return:

item2 undefined
item2 undefined
item2 undefined

My question is - how would you modify this code so that it returns the result we're expecting?

item0 1
item1 2
item2 3
Community
  • 1
  • 1
dwjohnston
  • 11,163
  • 32
  • 99
  • 194

1 Answers1

1

Use an IIFE in the for loop in buildList and pass in the i.

This will ensure that the i passed in will remain enclosed in the IIFE closure and will not be changed by the i in the for loop

function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    //the IIFE
    (function(i) {
      var item = 'item' + i;
      result.push(function() {
        console.log(item + ' ' + list[i])
      });
    })(i);
  }
  return result;
}

function testList() {
  var fnlist = buildList([1, 2, 3]);
  // Using j only to help prevent confusion -- could use i.
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
}

testList();
Community
  • 1
  • 1
AmmarCSE
  • 30,079
  • 5
  • 45
  • 53