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

203
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 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