This commit is contained in:
Ilya Kantor 2020-09-10 19:02:34 +03:00
parent 0168147c81
commit c65a1e85b8
5 changed files with 20 additions and 101 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Before After
Before After

View file

@ -1,5 +1,5 @@
Let's examine what's done inside `makeArmy`, and the solution will become obvious. Let's examine what exactly happens inside `makeArmy`, and the solution will become obvious.
1. It creates an empty array `shooters`: 1. It creates an empty array `shooters`:
@ -27,11 +27,11 @@ Let's examine what's done inside `makeArmy`, and the solution will become obviou
3. The array is returned from the function. 3. The array is returned from the function.
Then, later, the call to `army[5]()` will get the element `army[5]` from the array (it will be a function) and call it. Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (that's a function) and call it.
Now why do all such functions show the same value, `10`? Now why do all such functions show the same value, `10`?
That's because there's no local variable `i` inside `shooter` functions and neither in the code block of `while {...}`. When such a function is called, it takes `i` from its outer lexical environment. That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment.
What will be the value of `i`? What will be the value of `i`?
@ -51,11 +51,11 @@ function makeArmy() {
} }
``` ```
We can see that it lives in the lexical environment associated with the current `makeArmy()` run. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (at the end of `while`). We can see that all `shooter` functions are created in the lexical environment, associated with the one `makeArmy()` run. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10`(`while` finishes at `10`).
As a result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`. As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`.
![](task-while-lexenv-makearmy.svg) ![](lexenv-makearmy.svg)
As you can see above, on each iteration of a `while {...} ` block, a new lexical environment is created. This implies that as long as we store the value of `i` in a variable in the `while {...}` block, created Lexical Environment will have that variable with value of `i`. As you can see above, on each iteration of a `while {...} ` block, a new lexical environment is created. This implies that as long as we store the value of `i` in a variable in the `while {...}` block, created Lexical Environment will have that variable with value of `i`.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 61 KiB

View file

@ -14,22 +14,28 @@ function makeArmy() {
let i = 0; let i = 0;
while (i < 10) { while (i < 10) {
let shooter = function() { // shooter function let shooter = function() { // create a shooter function,
alert( i ); // should show its number alert( i ); // that should show its number
}; };
shooters.push(shooter); shooters.push(shooter); // and add it to the array
i++; i++;
} }
// ...and return the array of shooters
return shooters; return shooters;
} }
let army = makeArmy(); let army = makeArmy();
army[0](); // the shooter number 0 shows 10 *!*
army[5](); // and number 5 also outputs 10... // all shooters show 10 instead of their numbers 0, 1, 2, 3...
// ... all shooters show 10 instead of their 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.
*/!*
``` ```
Why do all of the shooters show the same value? Fix the code so that they work as intended. Why do all of the shooters show the same value?
Fix the code so that they work as intended.

Binary file not shown.