Does pushing inside a for loop not increment a declared Let in its scope?

Asked

Viewed 92 times

2

I was reading the series You Don’t Know JS which says the following about let declared in for loops:

There’s a special behavior defined for let declarations used in the head of a for-loop. This behavior says that the variable will be declared not just Once for the loop, but each iteration. And, it will, helpfully, be initialized at each subsequent iteration with the value from the end of the Previous iteration.

Now, I tried that the other day:

var numeros = [4, 5, 6];
var n = [];
for (let l = n.length; l < numeros.length;) {
    n.push(numeros[l] * 2);
}
// [8, 8, 8, 8, 8,...] loop infinito

However, this works as expected:

for (;n.length < numeros.length;) {
    n.push(numeros[n.length] * 2);
}
// [8, 10, 12]

It is interesting what happens by mixing the two cases, because the l does not change with each iteration:

for-loop-let.gif

I hoped that l change in all cases, why is not what happens?

  • I’ll ask you then in a simple way, because the question has nothing to do with closure, but, yes the link has examples of such, what is your real doubt? is to know if the let of the variable is always redeclared in each passage in the for or what is the difference between the two forms? what you expect as an answer, because it’s very easy to say that I’ve gone out of focus, but the other answer has also gone out of focus and said that there are ways to do it differently is not the focus of the question.

  • The question is the one that is above even, why the let is not redeclared at every iteration. I still don’t understand why. I suspect that, as you said, only the incrementing/decreasing field would change the value of what is declared there in the first expression, and then makes sense with the link example, because it uses the third expression of the for. However, I think that a more dedicated research into the specification of Ecma could bring greater clarification.

  • in my vision if you don’t care closure you want to know the difference between the two for of your question and this may be confused.

  • though I understood, that your doubt is because the n increasing and you think that this value is being passed again to l, and this will not happen, because the first only passes the initial value ... its increment is either done in the third parameter that is ideal or in the body of the for!

  • 1

    Right. I think it’s reasonable. I’ll take a look at the specification.

  • when a debug is done, for example it only passes on startup once. understood?

  • Yes, I get it. You’ve emphasized that very strongly.

Show 2 more comments

2 answers

2

Because that site of for is exactly for initialization, it only runs once, it is not part of the loop itself, it is a preprocessing that occurs to start the loop. It’s almost as if he was declared before the for, is only different because its scope is only within the for.

Why not change the value of l? Because you didn’t have it changed anywhere. The variable won’t magically change its value by itself. I understand that you thought the statement there (let l = n.length) would be executed at each step of the loop and so the variable would be modified with the new size of the array (your code was smart to create an interesting situation to show this), but it is not so, missed to know that precisely that stretch is only executed before starting the loop.

The condition code and the code that determines the step (usually an increment) that you did not use is executed at each step, and the step code is executed before the condition. And of course, everything that’s inside the code block tied to for will also run every time.

Note that the context of the explanation speaks of closures, where the use of a loop variable has strong implications, and then the explanation makes sense. Not that I think the explanation cited as a well-done text gives the wrong impression. I don’t want to go into detail because the question is about the for and the code posted does not have a closure, but what will happen is that each closure will have a different object pointing to the value of i according to its value at the time of the creation of the closure. Without the closure this does not happen and there is the effect you are wanting to demonstrate, even if the variable was being changed.

  • In this case, I could not understand the connection with closures, but rather that the variable declared there can only be changed with the third expression of for loop (increment/decrement), as @Virgilionovik explained in the first line.

  • That’s not true either.

  • Well, why don’t you?

  • Because there are several other ways to change a variable. In the answer below is not explaining what you asked, is just saying what to do not get into loop infinite which is not the focus of the question. To tell you the truth I have my doubts if the quote you posted is really that, in other languages it is not, it may just be that the text did not get good and that’s why it caused the wrong understanding. Even the idea of the text only makes sense in the context of closure because there are several objects being captured, but this has to do with the closure and not the for.

1

The reason is because you didn’t put the increment (l++) and therefore of loop infinite, basic example:

var numeros = [4, 5, 6];
var n = [];
for (let l = 0; l < numeros.length;l++) {
    n.push(numeros[l] * 2);
}

console.log(n);

although there is a much more practical way to do this:

var numeros = [4, 5, 6];
var n = numeros.map(function(n) { return n * 2 });
console.log(n);

the second form

for (;n.length < numeros.length;) {
    n.push(numeros[n.length] * 2);
}

worked because the n increasing the number of positions until adding all of the other array and only has the part of the condition that is the only thing necessary for the completion of that for

Browser other questions tagged

You are not signed in. Login or sign up in order to post.