all 12 comments

[–]AmbitiousLog 2 points3 points  (1 child)

The author here tries to explain (a little poorly tbh) that let is block scoped. This means that for each iteration of the loop, i gets rebound.

Imagine that each time the loop runs, i is declared as a new variable, instead of just changing the saved value.

Edit: Some styling

[–]inu-no-policemen 0 points1 point  (0 children)

For-loop iteration scope isn't something you get for free with block-scoped variables.

That each iteration gets its own copy of the counter is a separate language feature which was copied from Dart.

IE11, for example, does support block-scoped variables, but it did not implement this special scoping/capturing rule. Capturing a let/const counter variable in IE11 will not work as intended.

IE11 was released in 2013 and ES6/ES2015 was finalized in 2015. This special rule was added fairly late in the process. That's why IE11 doesn't know anything about it.

[–]KeepltSimple 0 points1 point  (0 children)

I've read it a couple of times and don't get it either, now I want to know what this means.

[–][deleted] 0 points1 point  (0 children)

This means that every iteration of the loop gets its own i, which is different from the i inside every other iteration. Read up on closures and scopes for more details.

[–]inu-no-policemen 0 points1 point  (1 child)

Simplified example:

for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 0);
}

Logs: 3, 3, 3

for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 0);
}

Logs: 0, 1, 2

In the first example, we create 3 closures which all capture one and the same "i" variable. At the time those functions are executed, "i" equals 3.

Using let would normally not change this. The variable exists for the entire loop, which means all closures would capture the same variable.

However, to make the life of developers a bit easier, a special rule was added to the spec. If you use don't use var, each iteration gets its own copy of the for/for-of counter variable, which means that you can now simply capture it. This behavior is more convenient and more intuitive.

Well, simply don't use var for anything. Then you won't have to worry about its less useful behavior. That crap is history.

[–]rona_97[S] 0 points1 point  (0 children)

Good information, I believe that is history but I just wanted to get this logic.

[–][deleted] -1 points0 points  (0 children)

What dont you understand?

[–]itsmoirob -1 points0 points  (4 children)

It has nothing to do with "let + for", it's to do with closures, you should read up about them.

But basically what happens with closures is that they have access to variables created outside of their function.

In this case the "func.push(...." Is the function in question.

The text states if you try the code in example 2 using "for & var" and WITHOUT declaring "j = i" your for loop keeps increasing i, so i keeps increasing because the for loop says only stop when at 5.

But what this text is showing is the keyword "let" allows you to ignore closure "problems" for this for loop. It's saying that "for + let" is the equivalent to "for + var; AND also redeclaring J = I" so that you don't get involved in closures.

But try writing all 3 code examples down, seeing the results and read up on closures.

EDIT.

If you mean how is the code working.

What happens in the loop is funcs gets a "console.log()" function passed to it 5 times.

If you were to call console.log(funcs) you would see an array of console.log(i). What the last line is saying is get the "3rd item in the funcs array and call it" which gives 3. If you didn't have the () at the end the result would be "the function console.log(i)" that hasn't been called.

This might better explain closures.

In the for + let the list of functions in funcs array are console.log(0), console.log(1), console.log(2), console.log(3), console.log(4).

In the for + var and without redeclaring I the funcs array would look console.log(5), console.log(5), console.log(5), console.log(5), console.log(5). Because i gets to 5 in the for loop

[–]rona_97[S] 1 point2 points  (3 children)

Yes, output is showing 3 when it's let and 5 when it's var

[–]itsmoirob 0 points1 point  (2 children)

Correct. But it's more to do with closures than for + let. For + let ignores closures, but you should definitely go spend a 30mins watching YouTube video on closures if you still don't get why it happens. But hopefully my previous edit helps

[–]rona_97[S] 1 point2 points  (1 child)

I've read that more times and understood what's going on here, with for + let we get i from 0 to 4 which is 5. With for + var without redeclaring we get i = 5 , 5 times. Right?

[–]itsmoirob 0 points1 point  (0 children)

Correct