Compare Scopes of the var and let Keywords I need an explanation please

<%= @topic_view.topic.title %>
<%= @topic_view.topic.average_rating %> <%= @topic_view.topic.posts.count { |p| !!p.custom_fields['rating'] } %>

Tell us what’s happening:
Why does this code return 3 instead of 2, I didn’t understand FCC’s explanation?

I appreciate your feedback.

Your code so far

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

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/compare-scopes-of-the-var-and-let-keywords

You might find a better explanation here.

var printNumTwo;
/* in the initialization section of this for loop, the variable i is created. it's 
 * scope is not limited to the for loop - it's the same i if you were to reference
 * it at any point after this initialization.
*/
for (var i = 0; i < 3; i++) {
  if(i === 2){
/* when the printNumTwo function is created, it is set to return the value pointed
 *  to by the label i. That value is 2 at the time of the function creation, but the 
 * loop continues to run until i is equal to 3. Once i equals 3, the test condition
 *  in the for loop fails and the loop exits.
 */
    printNumTwo = function() {
      return i;
    };
  }
}
/* The function printNumTwo() returns the value pointed to by the label i, so the
 *  console.log() call will print the value that i points to at the time the function is 
 * actually called. Because i was set to 3 at the point the loop exited, 
 * that value is 3
 */
console.log(printNumTwo());
// returns 3
1 Like