I couldn’t follow the explanation given in the example of challenge " ES6: Compare Scopes of the var and let Keywords". Can someone explain?
It says that if we use var in the for loop, the function printNumwo returns 3 and not 2. I don’t understand the reason? Ain’t we were doing this in all ES5 challenges?
I’m going to quote a post I made on a similar question:
This gets asked a lot, because I suspect we don’t necessarily explain very well what actually happens around a for loop
This is going to possibly be a confusing explanation to read but it might help in future for other loop related questions you may have
When we have for(a; b; c){d; } where a, b, c, d are parts of the for loop, the following happens:
The expression a is executed once
b is executed, and if falsy (or false) go to 6
The body of the loop, d, is executed once
c is executed once
go to 2.
continue with the line after the loop body
Note that c is executed before b's test
The different keywords var and let control which scopes a variable is still defined in, and behave differently for variables defined in the a part of the loop, but that’s what this question will end up showing so I’ll leave it here
Edit: Realised my older explanation of a loop is a little inaccurate
" When you declare a variable with the let keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression."
If the let variable is defined inside a function, as in the example below, it has only local scope:
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
// returns 2
console.log(i);
// returns "i is not defined"
I believe @Yogita25 is more interested why the output of printNumTwo() is changing depending on var vs let. And the answer to this is way more tricky. When using let, it creates a block scope and eventually a closure printNumTwo (sort of a link between block scope of for loop and global scope). When invoked, it executes in that block scope, where i === 2.
On other hand, var doesn’t create block scope and function printNumTwo is declared in the global scope, basically same as like this:
var printNumTwo = function() {
return i;
}
for (var i = 0; i < 3; i++) {
if(i === 2){
// I won't declare anything today!
}
}
console.log(printNumTwo());
It’s not a great example, and yeah the description is confusing if you’re a beginner. It’s quite important though, because understanding JS scope is pretty central to understanding how to program JS.
var is not block scoped, which means that i still lives once the loop has finished. This means you could potentially keep using i [normally happens accidentally] after the loop is over. And it can cause problems with functions inside the loop — particularly if you define a function in the loop.
for (var i = 0; i < n; i++) {
// use i
}
let is block scoped: once you get past the closing } on that loop, the variable is done with, none of the above problems apply. This is what most people would expect to happen; let is basically var that works sensibly.
for (let i = 0; i < n; i++) {
// use i
}
The change is quite subtle — its designed to make specific easily made and hard-to-debug errors less common. Use let for for loops, anyway
Thanks @snigo & @DanCouper. I now understand that let helps us distinguish between variables declared in global and local scope. I still have one doubt in the example given (sorry, freecodecamp is not allowing me to paste the link to the page. probably because I am a new user). Here printNumTwo is declared in global scope and then used inside the for loop. What is I declare the variable printNumTwo inside the for loop? I mean is there any specific reason because of which we are declaring the variable in global scope?