ES6 Exercise 1

Ramon skipped over some of the write-up on this first exercise, but I am a bit confused by this bit of code:

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

Since i is declared entirely within the scope of the for loop, doesn’t it cease to exist once the for loop completes? So then how does it even work to call printNumTwo() after the fact? By the time the function is called, the value it needs to return is based on a variable that seems like it should no longer exist.

2 Likes

Hi Steven,

This is really a good question, and the explanation would probably go way beyond the scope of this bootcamp. The reason we have the ES6 section in the first place is because it solves a few concrete problems that existed in earlier versions of JS. Notably “closures and loops”, which all have to do with scope. Before we had let and const there was no ‘block scoping’ but only function scoping and that caused quite some side effects.

I will link you to a (maybe too complex) example of a discussion, to see if that makes sense. A comment on that post explains largely what is going on:

JS functions “close over” the scope they have access to upon declaration, and retain access to that scope even as variables in that scope change. Each function in the array above closes over the global scope (global, simply because that happens to be the scope they’re declared in). Later those functions are invoked logging the most current value of i in the global scope. That’s JS : ) let instead of var solves this by creating a new scope each time the loop runs, creating a separated scope for each function to close over. Various other techniques do the same thing with extra functions.

The full discussion is here:

And a technical discussion of scoping here (this one requires quite some grit to get through)

Perhaps not the easy answer you were after, but I hope it provides some insights. Let me know if you have follow up questions.

2 Likes

So by “close over,” it means that the function kind of “locks in” the variable as it existed when it was declared? That would make sense, because if it didn’t work that way, the function would be otherwise fundamentally broken and uncallable.

2 Likes

Yes - you are on your way understanding that! But in our ‘var’ time this would yield undesired side effects (try it using var like the examples in the linked post). Thus the concept of ‘block scoping’ was introduced in ES6, using ‘let’ and ‘const’. It made some code less complex and solved some issues along the way. I believe that is the main reason for this particular lesson.

There are some videos ‘out there’ that describe JavaScript ‘the weird parts’ and explain this in close detail definitely worth watching when you are ready to move beyond the ‘beginner’ stage (don’t do that yet, it may be a bit too complex). But this one, explains succinctly what a closure is AND as bonus it shows what happens if you do use the ‘var’ variable instead. It used to be a trick JS interview question (and may still be used now):

(and it is less than 5 minutes :slight_smile: )

I hope that helps too!

3 Likes

This was super helpful. Thanks so much! And it’s good to know to be on the lookout for a trick question involving this concept.

2 Likes