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

208
Vistas
Why doesn't assigning variables inside a function copy instead of referencing it

I have this code:

function makeArmy() {
  let shooters = [];

  let i = 0;
  while (i < 10) {
    let shooter = function () {
      console.log(i);
      // that should show its number
    };
    shooters.push(shooter); // and add it to the array
    i++;
  }

  // ...and return the array of shooters
  return shooters;
}

let army = makeArmy();

// all shooters show 10 instead of their numbers 0, 1, 2, 3...
army[0](); // 10 from the shooter number 0
army[1](); // 10 from the shooter number 1
army[2](); // 10 ...and so on.

This happens because i is always a reference to the outer i inside the makeArmy() function.

If we adjust the code to be:

function makeArmy() {
  let shooters = [];

  let i = 0;
  while (i < 10) {
    // copy the varible i into the while lexical scope
    let j = i
    let shooter = function () {
      console.log(j);
      // that should show its number
    };
    shooters.push(shooter); // and add it to the array
    i++;
  }

  // ...and return the array of shooters
  return shooters;
}

let army = makeArmy();


army[0](); // 0
army[1](); // 1
army[2](); // 2

The above code works as expected because instead of referencing the variable i inside shooter() we are copying it into j, thus making it available to the shooter function in its own scope.

Now, my question is, why doesn't copying the i variable inside the function itself work? even though I'm effectively still copying the variable? What am I missing here?

Code:

function makeArmy() {
  let shooters = [];

  let i = 0;
  while (i < 10) {
    let shooter = function () {
      let j = i;

      console.log(j);
      // that should show its number
    };
    shooters.push(shooter); // and add it to the array
    i++;
  }

  // ...and return the array of shooters
  return shooters;
}

let army = makeArmy();

// all shooters show 10 instead of their numbers 0, 1, 2, 3...
army[0](); // 10 from the shooter number 0
army[1](); // 10 from the shooter number 1
army[2](); // 10 ...and so on.
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Because you are copying at a time at which i is already 10.

In fact, with let j = i in the inner function, there will be no difference to using i directly, because that assignment also executes only when you invoke that inner function, and as said, at this point i will already be 10, since the invocation happens long after the loop completed, in e.g. army[0]().

As you noted, it works if you move the let j = i outside of the inner function (but still inside the loop). This way, the assigment to the local variable(s) j happens on each iteration immediately, and the inner function later refers to those 10 different j's with their right values that were previously set at that point in time when i had the respective value that you wanted.


By the way, this problem won't exist if you'd use a for loop instead because for with let has some "magic" that creates a semi-separated scope for each iteration (the exact way this works is a bit more complicated).

  for (let i = 0; i < 10; i++) {
    let shooter = function () {
      console.log(i);
    };
    shooters.push(shooter);
  }
about 4 years ago · Juan Pablo Isaza Denunciar

0

When you call console.log(i) in your shooter function i's value refers to the one that has once the while loop ended, thus i would be the last value it had. In your case i's value changes over time, showing the last value it had. When you assign that to a variable (let j = i) you copy that value and not the reference so it gives you the result you want.

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