Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

186
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda