-2

I know the outcome of this is 10:

var es = [];
for (var i = 0; i < 10; i++) {
  es[i] = function () {
    console.log(i);
  };
}
es[6]();

Any number of es[0] - es[9] is still 10. but why?

FairyQueen
  • 2,283
  • 7
  • 37
  • 57

4 Answers4

5

Because after the loop i is 10. The function prints the reference of i.

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
3

There is only integer object created. Those console.log(i) are all referring to the same object in memory. The value of i - the only i - is of course 10 at the end of the loop.

Note the line console.log(i) creates a closure, which in particular means it's not creating a new reference to the variable referred to by i. It's the same reference.

A good way to do this analysis is to keep tracking of the number of times in your code a new actual variable is created. If you've programmed in C or C++ or wherever, you know that an integer takes 4 or 8 bytes of memory. The line for(var i = 0; can be thought of as creating one object. Just one. Nothing inside of the function creates another object, since closures don't do that.

djechlin
  • 59,258
  • 35
  • 162
  • 290
2

That's because by the time you execute console.log(i), i has changed as the loop finished.

More precisely, the for loop stops when the condition i < 10 is false, that is when i is 10. What you have after that is 10 identical functions, all using the same, externally defined variable i.

You can fix it using this classical closure trick :

var es = [];
for (var i = 0; i < 10; i++) {
   (function(j){
     es[j] = function () {
       console.log(j);
     };
   })(i);
}
es[6]();

What this code does is create a new variable, j, whose scope is the anonymous function call. This is a way to save the value i has when the function is called (that is during the loop instead of when es[6] is called).

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Hum, why the downvote ? I'm the only one here to answer with working code... – Denys Séguret Sep 04 '13 at 19:59
  • 1
    Yes, wyh? This answer not only correctly answers the question but also gives valid code example for intended behaviour of asker. – Kemal Dağ Sep 04 '13 at 20:04
  • Only improvement I would make is to change the parameter name from `i` to avoid confusion. Otherwise looks good to me. – Marc Sep 04 '13 at 20:38
  • Why wouldn't the answer be 9 though? Because its i < 10. Also, I dont understand why if it's in a for loop it only prints once. Can you explain these things? – FairyQueen Sep 05 '13 at 11:29
  • The loop stops when i<10 isn't true anymore. It means that at just after the loop, i is 10. Your for loop doesn't print the numbers : it creates functions (all identical), and you call only one of those functions. – Denys Séguret Sep 05 '13 at 11:51
1

Because you are referring to i and after the loop it is 10i.e, when you are executing console.log(i). The value of i has changed to 10.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331