Functions has access to it own lexical as well outer environment

55 Views Asked by At

Functions has access to it own lexical as well outer environment but it's not working or maybe I don't understand why it's working like that.

Here is the code

function makeArmy() {
    let shooters = [];
  
    let i = 0;
    while (i < 10) {
      let shooter = function() {
        console.log( i );
      };
      shooters.push(shooter);
      i++;
    }

    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.

Fixed code


while (i < 10) {
      let j = i; // added variable to while loop (lexical  environment)
      let shooter = function() { 
        alert( j );
      };
    shooters.push(shooter);
    i++;
  }

But why don't it work like this when i define variable with J inside the function! Shooter function has it's own lexical environment.


while (i < 10) {
      let shooter = function() {
      let j = i; // define J inside function but still it gives 10 why?
        console.log( j );
      };
      shooters.push(shooter);
      i++;
    }

2

There are 2 best solutions below

0
StriplingWarrior On BEST ANSWER

Even though you define the variable j inside of the function (let j), you aren't initializing that variable (j = i) until the function gets executed.

At the time when the function instance is created, the reference to the outer variable i is "closed over," so the function can access the value of i when it gets executed. But it's not executed until after you've completed the loop, so let j = i causes j to have the same value that i has at the end of your loop.

1
Konrad On

Kind of the same code but simpler

let x = 0
const a = []
a.push(() => console.log(x))
{
  // creates a new variable
  const y = x
  a.push(() => console.log(y))
}
// x is changed but y is not
x = 1
// prints 1
a[0]()
// prints 0
a[1]()