Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

187
Visualizações
Behavior of let variables declared inside for loop in context of closures

In below snippet, the function passed to setTimeout forms a closure with the variable i which is present in the script scope. So the function contains a reference to variable i. The value of i is updated to 5 before i is logged to console. And the output is: 5 5 5 5 5 (with newlines)

script.js:

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

The above part is clear to me. But when I declare variable i inside for loop, then i is block scoped to the for loop.

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

In this code snippet, I expect the output to be same as output of first snippet, because the closure contains reference to the variable i and the value at that reference should be updated to 5 before the value is logged to console. But the actual output is: 0 1 2 3 4 (with newlines)

The question is, why the code in second snippet behaves this way?

It it because:

  1. A new copy of variable i is created in memory for each iteration of for loop and previous copy is garbage collected? I'm not sure how memory management works for loops.
  2. Instead of storing reference of i, the value of i is stored in closure? I don't think this is the case.
  3. Anything else?

Please help to clarify. Thanks!

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Your question mentions a few implementation details. Yet, these implementation details don't matter when answering your question.

You are indeed right, that there is some specific behavior of the for-loop occurring. Let's look at the ECMAScript 2021 standard here:

When your for-loop with let is evaluated, these steps are performed first:

enter image description here

Steps 4, 9 and 10 are particularly interesting to us. Step 4 gathers all const and let variables declared in the for-loop.

Step 9 sets perIterationLets to the let variables (if there are let variables) or to the empty list otherwise. Step 10 then calls ForBodyEvaluation to actually run the loop:

enter image description here

Here, let's focus on 3.e and take a closer look at CreatePerIterationEnvironment:

enter image description here

Carefully following the invocation hierarchy, we note that perIterationBindings is the list perIterationLets of let variables we gathered before.

In lines e.i, e.ii, e.iii, we now create a new binding (think of this as the memory location where the variables lives) and copy the value of the variable with the same name from the previous iteration into it. It is a different new variable though, even if it has the same name!

Thus if a closure inside a loop body captures the current context, the loop variables will not change, because each loop body iteration has its own current context.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda