ES6: var & let comparison

ES6: var & let comparison
0

#1

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?


#2

@Yogita25, could you please provide the code itself


#3

@iiiked, here is the link to the problem


#4

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:

  1. The expression a is executed once
  2. b is executed, and if falsy (or false) go to 6
  3. The body of the loop, d, is executed once
  4. c is executed once
  5. go to 2.
  6. 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


#5

Here is the key sentence from that problem:

" 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"

#6

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());

#7

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


#8

Thanks @iiiked & @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?


#9

Thanks pulamusic. My understanding is better than earlier after going through the discussion in the post.