-2

Here is a piece of code :

// -------- Sample 1 --------------- 
var funcs = [];
for (var i = 0; i < 3; i++) {  
    funcs[i] = function() {  
        console.log("My value: " + i); 
    };
}
for (var j = 0; j < 3; j++) {
  funcs[j](); 
}

// --------- Sample 2 --------------
var fun = [];
for(var i = 0;i < 3; i++) {
    fun[i] = function() {
        console.log('values is '+ i);
    }
}
for(var i = 0; i < 3; i++) {
    fun[i]();
}

Both the sample codes are same except the variable names. But it's giving different output. The output of the above code is :

My value: 3
My value: 3
My value: 3
values is 0
values is 1
values is 2

Can any one figure out why its happening ? DEMO

Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
iJade
  • 23,144
  • 56
  • 154
  • 243

1 Answers1

2

var is hoisted, so to the interpreter, the first part's i actually looks more like this:

var funcs = [];
var i;
for (i = 0; i < 3; i++) {      
  funcs[i] = function() {          
    console.log("My value: " + i); 
  };
}
// At this point, the for loop has finished; `i` has the value of 3 now:
for (var j = 0; j < 3; j++) {
  // Each function retrieves the value of i and displays it
  // and since `i` is 3, each function displays 3:
  funcs[j]();                     
}

In your second sample (which is somewhat invalid JS because i gets declared twice), i gets reassigned to values 0, 1, and 2 while looping over the function that displays i.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 2
    rite. Then why doesn't the same happen with the sample 2 code? – iJade Mar 28 '18 at 05:00
  • Because in your second sample, `i` gets reassigned to values 0, 1, and 2 *while looping over the function that displays `i`.* – CertainPerformance Mar 28 '18 at 05:01
  • No, the first sample, while looping over executing the functions, uses `j`, not `i`. If this was not immediately apparent to you, which is perfectly understandable, it should serve as a nice reminder why not to use single-letter variable names :) – CertainPerformance Mar 28 '18 at 05:06