1

Take a look at this code:

var arr = new Array();
for (var i = 0; i < 10; i++) {
    arr[i] = {
        func:function() {
            console.log(i);
        }
    }
}
arr[0].func();

I am confused by this, because I thought this would work. I basically would like each object in the array to print the value it was given when the function was created.

Right now when I call func(), it prints 10 in the console. Is there a way to make it print 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 instead? Thanks!

Keiran Paster
  • 600
  • 2
  • 7
  • 21

3 Answers3

1

The problem is that the function inside is referencing the variable 'i' which increases every time. You can store the value of 'i' in each iteration in the object alongside the function like this:

http://jsfiddle.net/Sgnvp/

var arr = new Array();
for (var i = 0; i < 10; i++) {
    arr[i] = {
        func:function() {
            console.log(this.value);
        },
        value: i
    }
}
arr[0].func();
thebreiflabb
  • 1,504
  • 10
  • 19
0

You have to create a closure to encapsulate the value. Here I'm calling consoleIt and passing it i. consoleIt creates a closure around the i

var arr = [];

function consoleIt (i) {
    return function () {
        console.log(i);
    }
};

for (var i = 0; i < 10; i++) {
    arr[i] = { 
        func: consoleIt(i)
    };
}

arr[0].func();
Chad
  • 18,076
  • 8
  • 31
  • 41
0

This is no better really than the way that thebreiflabb did it, but it's an interesting technique that's worth knowing:

    var arr = [];

    for (var i = 0; i < 10; i++){

      (function(i){
        arr[i] = {
          func : function(){
            console.log(i); 
          }
        };
      })(i);

    }

    arr[0].func();

It just uses an anonymous closure to scope i.

Zevan
  • 10,097
  • 3
  • 31
  • 48