0
    var arr = []
    for(var i=0; i<5; i++){
        arr[i] = function(){
            return i;
        }
    }
    for(var index in arr){
        document.write(arr[index]())};

what i expected to see was 12345, but the outcome is 55555

let me explain my logic below by using '//'

    var arr = []                   // creating array new object
    for(var i=0; i<5; i++){            
        arr[i] = function(){
            return i;
        }             
    // arr = [function(){return 0}, function(){return 1}, function(){return 2}, function(){return 3}, function(){return 4}
    }
    for(var index in arr){
        document.write(arr[index]())};

    // outcome is 12345

i`ve already read the article JavaScript closure inside loops – simple practical example,

but still cannot understand..

jwkoo
  • 2,393
  • 5
  • 22
  • 35

2 Answers2

1

The problem is that i is 5 by the time any of those functions is called

By the way, I'd expect 01234 as the output

In new browsers (not internet exploder) you can simply change the var i to let i

var arr = []
for(let i=0; i<5; i++){
    arr[i] = function(){
        return i;
    }
}
for(var index in arr){
    console.log(arr[index]())
}

but that doesn't help internet exploder - so, running this through a transplier (babel for example) you get

"use strict";

var arr = [];

var _loop = function _loop(i) {
    arr[i] = function () {
        return i;
    };
};

for (var i = 0; i < 5; i++) {
    _loop(i);
}

for(var index in arr){
    console.log(arr[index]())
}
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
1

That's because in your for loop, var i is not block-scoped. Meaning, you can access i outside the loop. So, after you created the functions inside the loop which returns i, and execute those functions outside, it will have i = 5, because that's the last value you assigned to i. You need to use let instead of var to have a block-scoped variable which you would use in your loop.

Rax Weber
  • 3,730
  • 19
  • 30
  • thanks, but still wondering about this issue, i thought that arr would be determined, i mean, arr = [function(){return 0}, function(){return 1}, function(){return 2}, function(){return 3}, function(){return 4}, but in your explanation, arr = [function(){return i}, function(){return i}, function(){return i}, function(){return i}, function(){return i}, i instead of concrete numbers, later refering the i=5. am i undertstand correctly..? – jwkoo Jun 29 '17 at 06:36
  • Yes that's correct. – Rax Weber Jun 29 '17 at 06:40
  • thank you so much, little bothering extra question,, why not arr = [function(){return 0}, function(){return 1}, function(){return 2}, function(){return 3}, function(){return 4} ? isn`t (return i`s i) same as (for var i`s i) ? why still remaining just i? instead of concrete numbers? – jwkoo Jun 29 '17 at 06:45
  • Because you are just **defining** functions, not executing it inside the loop. By the time you execute a function, it looks for the value of `i`, which in your case has the most recent value of 5. – Rax Weber Jun 29 '17 at 06:49
  • ahha... just because of that yet-function-call? i was confused because the arr[i]`s i is increasing, reflecting the 1,2,3,4,5 otherwise return i`s i still remaining just i ... thanks for your help and i really appreciate it, – jwkoo Jun 29 '17 at 06:56