Merge pull request #2127 from MuhammedZakir/master
Improve make-army task
This commit is contained in:
commit
c48c52cb81
1 changed files with 96 additions and 97 deletions
|
@ -6,7 +6,7 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco
|
||||||
```js
|
```js
|
||||||
let shooters = [];
|
let shooters = [];
|
||||||
```
|
```
|
||||||
2. Fills it in the loop via `shooters.push(function...)`.
|
2. Fills it with functions via `shooters.push(function)` in the loop.
|
||||||
|
|
||||||
Every element is a function, so the resulting array looks like this:
|
Every element is a function, so the resulting array looks like this:
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco
|
||||||
|
|
||||||
3. The array is returned from the function.
|
3. The array is returned from the function.
|
||||||
|
|
||||||
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.
|
Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (which is a function) and calls 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. 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`?
|
Then, what will be the value of `i`?
|
||||||
|
|
||||||
If we look at the source:
|
If we look at the source:
|
||||||
|
|
||||||
|
@ -45,21 +45,20 @@ function makeArmy() {
|
||||||
let shooter = function() { // shooter function
|
let shooter = function() { // shooter function
|
||||||
alert( i ); // should show its number
|
alert( i ); // should show its number
|
||||||
};
|
};
|
||||||
...
|
shooters.push(shooter); // add function to the array
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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`).
|
We can see that all `shooter` functions are created in the lexical environment of `makeArmy()` function. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (`while` stops at `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`.
|
As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
As you can see above, on each iteration of a `while {...} ` block, a new lexical environment is created.
|
As you can see above, on each iteration of a `while {...}` block, a new lexical environment is created. So, to fix this, we can copy the value of `i` into a variable within the `while {...}` block, like this:
|
||||||
|
|
||||||
So, to fix a problem we can copy the value of `i` into a variable within the `while {...}` block, like this:
|
|
||||||
|
|
||||||
```js run
|
```js run
|
||||||
function makeArmy() {
|
function makeArmy() {
|
||||||
|
@ -118,13 +117,13 @@ army[0](); // 0
|
||||||
army[5](); // 5
|
army[5](); // 5
|
||||||
```
|
```
|
||||||
|
|
||||||
That's essentially, the same, as `for` on each iteration generates the new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration.
|
That's essentially the same, because, `for` on each iteration generates a new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Now, as you've put so much effort into reading this, and the final recipe is so simple - just use `for`, you may wonder: was it worth that?
|
Now, as you've put so much effort into reading this, and the final recipe is so simple - just use `for`, you may wonder -\- was it worth that?
|
||||||
|
|
||||||
Well, if you could easily answer the question of that task, you wouldn't read the solution, so hopefully this task must have helped you to understand things a bit better.
|
Well, if you could easily answer the question, you wouldn't read the solution. So, hopefully this task must have helped you to understand things a bit better.
|
||||||
|
|
||||||
Besides, there are indeed cases when one prefers `while` to `for`, and other scenarios where such problems are real.
|
Besides, there are indeed cases when one prefers `while` to `for`, and other scenarios, where such problems are real.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue