Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

204
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!