Is my explanation about let correct?

After reading Compare Scopes of the var and let Keywords challenge I’m trying to find an explanation how differently compiler acts when encountering let keyword as opposed to var keyword. And I don’t understand a reason the challenge gives about how let helps to avoid the problem.

A - First my explanation:

1- The following code uses var for i:

var printNumTwo;
for (var i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());

I’ve thought up this scenario: when i's value is 2 the if block executes and inside, we create a function and save it’s reference into printNumTwo variable. The function says return i. Here because i has been declared using var keyword and is global so we have access to i's value everywhere so the function returns what is saved into i variable whenever it’s called. So after calling printNumTwo() what is currently in i variable is printed to console which is the number after last update: 3.

2- The following code uses let for i:

let printNumTwo;
for (let i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
console.log(i);

I’ve thought up this scenario: when i 's value is 2 the if block executes and inside, we create a function and save it’s reference into printNumTwo variable. The function says return i . Here because i has been declared using let keyword and we don’t have access to it after for statement scope finishes, so the current value of i matters so the function returns the number 2 whenever it’s called. So after calling printNumTwo() number 2 is printed to console.

B - The challenge’s explanation I don’t understand:

printNumTwo() returned the correct value because three different i variables with unique values (0, 1, and 2) were created by the let keyword within the loop statement.

Why is that? Three different i? Isn’t it that the initialization expression of for loop is run just once? So still I think we have only on i which has been updated several times and the final value is 3.

Thank you very much for helping me.

I’m not sure if it is referring to re-binding, but that explanation does sound a little confusing.

YDKJS: let Loops

Not only does let in the for-loop header bind the i to the for-loop body, but in fact, it re-binds it to each iteration of the loop, making sure to re-assign it the value from the end of the previous loop iteration.

Here’s another way of illustrating the per-iteration binding behavior that occurs:

{
	let j;
	for (j=0; j<10; j++) {
		let i = j; // re-bound for each iteration!
		console.log( i );
	}
}