0
function makeFunctionArray(){
    const arr=[]

    for(var i = 0; i < 5; i++){
        arr.push(function(){console.log(i)})
    }
    return arr
}

const functionArr = makeFunctionArray()

functionArr[0]()

Can someone explain to me why functionArray[0] prints out 5 instead of 0? I get that using var i = 0 in the for loop means that i = 5 after the for loop ends (due to scope), but I don't see how that changes the first item in the array to be 5 instead of 0. Using let instead of var for i gives the right answer, but I can't wrap my head around as to why.

  • 1
    With `var`, the `i` variable referenced inside the pushed function refers to the (single) variable scoped to the function. After `makeFunctionArray` runs, its value is 5, so when the value is accessed later, 5 is the result. WIth `let`, each iteration has its own binding for the variable name - it's *not* scoped to the function, it's scoped inside the block, so the `i` for an iteration doesn't change. – CertainPerformance Apr 28 '20 at 22:14
  • Using `for (let i = 0; i < 5; i++) { ... }` is the equivalent of `for (var _i = 0; _i < 5; _i++) (function (i) { ...; _i = i; })(_i);`, assuming that any `break`, `continue`, and `return` statements in the `for` block get forwarded properly. – Patrick Roberts Apr 28 '20 at 22:17

0 Answers0