0

I'm trying to figure out why these anonymous functions are returning the last value of my loop iterator as opposed to the iterator's current value when it is set. I thought that values are exempt from pass by reference, but it looks like these return values are pointers to the original i?

function myFunctions(n) {

  var list = [];
  for (var i = 0; i < n; i++) {    
    list.push(function(){
        return i;
    });    
  }
  return list;
}

var res = [];

myFunctions(4).map(function(el){
    res.push(el());
});

var p = document.createElement('p');
p.innerHTML = res.join(',');
document.body.appendChild(p);

//expected result: 0,1,2,3

Reading material: Javascript by reference vs. by value

Fiddle: http://jsfiddle.net/ZP2hM/

Community
  • 1
  • 1
4m1r
  • 12,234
  • 9
  • 46
  • 58

1 Answers1

-1

this is a typical mistake people do using closures. Here is a fix:

for (var i = 0; i < n; i++) {  
    var tmp = i;  
    list.push(function(){
        return tmp;
    });    
  }

This happens because all functions in list array are bound to current i value. When your cycle finishes i = n-1; That is why you get n-1 for all array elements. This is resolved by temporary variable which is unique for each list element.

Anton L
  • 412
  • 4
  • 12
  • 1
    If you run the code you will notice that this does not fix the problem. You just gave `i` a different name. All functions have a reference to the same `tmp` variable. – Felix Kling Jul 24 '14 at 16:39
  • yes, this is not correct. I think the suggested answer above properly describes how to wrap this in a closure and capture the value. – 4m1r Jul 24 '14 at 16:39