images to svg
Before Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 57 KiB |
|
@ -84,7 +84,7 @@ Now it works correctly, because every time the code block in `for (let i=0...) {
|
|||
|
||||
So, the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration. That's why now it works.
|
||||
|
||||

|
||||

|
||||
|
||||
Here we rewrote `while` into `for`.
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ The Lexical Environment object consists of two parts:
|
|||
|
||||
For instance, in this simple code, there is only one Lexical Environment:
|
||||
|
||||

|
||||

|
||||
|
||||
This is a so-called global Lexical Environment, associated with the whole script.
|
||||
|
||||
|
@ -82,7 +82,7 @@ On the picture above, the rectangle means Environment Record (variable store) an
|
|||
|
||||
Here's the bigger picture of what happens when a `let` changes:
|
||||
|
||||

|
||||

|
||||
|
||||
Rectangles on the right-hand side demonstrate how the global Lexical Environment changes during the execution:
|
||||
|
||||
|
@ -110,7 +110,7 @@ That is why we can call a function declaration before it is defined.
|
|||
|
||||
The code below demonstrates that the Lexical Environment is non-empty from the beginning. It has `say`, because that's a Function Declaration. And later it gets `phrase`, declared with `let`:
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
### Inner and outer Lexical Environment
|
||||
|
@ -134,7 +134,7 @@ For instance, for `say("John")`, it looks like this (the execution is at the lin
|
|||
say("John"); // Hello, John
|
||||
```-->
|
||||
|
||||

|
||||

|
||||
|
||||
So, during the function call we have two Lexical Environments: the inner one (for the function call) and the outer one (global):
|
||||
|
||||
|
@ -156,7 +156,7 @@ Let's see how the search proceeds in our example:
|
|||
- When the `alert` inside `say` wants to access `name`, it finds it immediately in the function Lexical Environment.
|
||||
- When it wants to access `phrase`, then there is no `phrase` locally, so it follows the reference to the enclosing Lexical Environment and finds it there.
|
||||
|
||||

|
||||

|
||||
|
||||
Now we can give the answer to the first question from the beginning of the chapter.
|
||||
|
||||
|
@ -265,7 +265,7 @@ How does the counter work internally?
|
|||
|
||||
When the inner function runs, the variable in `count++` is searched from inside out. For the example above, the order will be:
|
||||
|
||||

|
||||

|
||||
|
||||
1. The locals of the nested function...
|
||||
2. The variables of the outer function...
|
||||
|
@ -319,7 +319,7 @@ Please note the additional `[[Environment]]` property is covered here. We didn't
|
|||
|
||||
1. When the script has just started, there is only global Lexical Environment:
|
||||
|
||||

|
||||

|
||||
|
||||
At that starting moment there is only `makeCounter` function, because it's a Function Declaration. It did not run yet.
|
||||
|
||||
|
@ -331,7 +331,7 @@ Please note the additional `[[Environment]]` property is covered here. We didn't
|
|||
|
||||
2. The code runs on, the new global variable `counter` is declared and for its value `makeCounter()` is called. Here's a snapshot of the moment when the execution is on the first line inside `makeCounter()`:
|
||||
|
||||

|
||||

|
||||
|
||||
At the moment of the call of `makeCounter()`, the Lexical Environment is created, to hold its variables and arguments.
|
||||
|
||||
|
@ -347,19 +347,19 @@ Please note the additional `[[Environment]]` property is covered here. We didn't
|
|||
|
||||
For our new nested function the value of `[[Environment]]` is the current Lexical Environment of `makeCounter()` (where it was born):
|
||||
|
||||

|
||||

|
||||
|
||||
Please note that on this step the inner function was created, but not yet called. The code inside `function() { return count++; }` is not running.
|
||||
|
||||
4. As the execution goes on, the call to `makeCounter()` finishes, and the result (the tiny nested function) is assigned to the global variable `counter`:
|
||||
|
||||

|
||||

|
||||
|
||||
That function has only one line: `return count++`, that will be executed when we run it.
|
||||
|
||||
5. When the `counter()` is called, an "empty" Lexical Environment is created for it. It has no local variables by itself. But the `[[Environment]]` of `counter` is used as the outer reference for it, so it has access to the variables of the former `makeCounter()` call where it was created:
|
||||
|
||||

|
||||

|
||||
|
||||
Now if it accesses a variable, it first searches its own Lexical Environment (empty), then the Lexical Environment of the former `makeCounter()` call, then the global one.
|
||||
|
||||
|
@ -371,7 +371,7 @@ Please note the additional `[[Environment]]` property is covered here. We didn't
|
|||
|
||||
6. The call to `counter()` not only returns the value of `count`, but also increases it. Note that the modification is done "in place". The value of `count` is modified exactly in the environment where it was found.
|
||||
|
||||

|
||||

|
||||
|
||||
So we return to the previous step with the only change -- the new value of `count`. The following calls all do the same.
|
||||
|
||||
|
@ -381,7 +381,7 @@ The answer to the second question from the beginning of the chapter should now b
|
|||
|
||||
The `work()` function in the code below uses the `name` from the place of its origin through the outer lexical environment reference:
|
||||
|
||||

|
||||

|
||||
|
||||
So, the result is `"Pete"` here.
|
||||
|
||||
|
@ -420,7 +420,7 @@ In the example below, the `user` variable exists only in the `if` block:
|
|||
alert(user); // Error, can't see such variable!
|
||||
```-->
|
||||
|
||||

|
||||

|
||||
|
||||
When the execution gets into the `if` block, the new "if-only" Lexical Environment is created for it.
|
||||
|
||||
|
|
Before Width: | Height: | Size: 22 KiB |
69
1-js/06-advanced-functions/03-closure/lexenv-if.svg
Normal file
After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 26 KiB |
90
1-js/06-advanced-functions/03-closure/lexenv-nested-work.svg
Normal file
After Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 9 KiB |
After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 25 KiB |