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/

2
  • I think at the time you call any of the functions the value of the variable i its 4. Commented Jul 24, 2014 at 16:36
  • Thanks, didn't know it was a closure issue, I didn't find the answers above. Commented Jul 24, 2014 at 16:43

1 Answer 1

-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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
yes, this is not correct. I think the suggested answer above properly describes how to wrap this in a closure and capture the value.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.