`let` in loop heads

In loops, you get a fresh binding for each iteration if you let -declare a variable. What does fresh binding mean here?

let arr = [];
for (let i=0; i < 3; i++) {
    arr.push(() => i);
}

From the book Exploring ES6:

var-declaring a variable in the head of a for loop creates a single binding (storage space) for that variable:

 const arr = [];
 for (var i=0; i < 3; i++) {
   arr.push(() => i);
 }
 arr.map(x => x()); // [3,3,3]

Every i in the bodies of the three arrow functions refers to the same binding, which is why they all return the same value.

If you let-declare a variable, a new binding is created for each loop iteration:

const arr = [];
for (let i=0; i < 3; i++) {
  arr.push(() => i);
}
arr.map(x => x()); // [0,1,2]

This time, each i refers to the binding of one specific iteration and preserves the value that was current at that time. Therefore, each arrow function returns a different value.

1 Like