Skip to content

Commit d391eb1

Browse files
committed
minor
1 parent 60772bb commit d391eb1

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

1-js/06-advanced-functions/03-closure/article.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Now we can give the answer to the first seed question from the beginning of the
157157

158158
That's because of the described mechanism. Old variable values are not saved anywhere. When a function wants them, it takes the current values from its own or an outer Lexical Environment.
159159

160-
So the answer here is `Pete`:
160+
So the answer to the first question is `Pete`:
161161

162162
```js run
163163
let name = "John";
@@ -188,7 +188,7 @@ And if a function is called multiple times, then each invocation will have its o
188188
```
189189

190190
```smart header="Lexical Environment is a specification object"
191-
"Lexical Environment" is a specification object. We can't get this object in our code and manipulate it directly. JavaScript engines also may optimize it, discard variables that are unused to save memory and perform other internal tricks.
191+
"Lexical Environment" is a specification object. We can't get this object in our code and manipulate it directly. JavaScript engines also may optimize it, discard variables that are unused to save memory and perform other internal tricks, but the visible behavior should be as described.
192192
```
193193

194194

@@ -216,22 +216,22 @@ function sayHiBye(firstName, lastName) {
216216

217217
Here the *nested* function `getFullName()` is made for convenience. It can access the outer variables and so can return the full name.
218218

219-
What's more interesting, a nested function can be returned: as a property of a new object (if the outer function creates and returns it) or as a result by itself. And then used somewhere else. No matter where, it still keeps the access to the same outer variables.
219+
What's more interesting, a nested function can be returned: as a property of a new object (if the outer function creates an object with methods) or as a result by itself. And then used somewhere else. No matter where, it still keeps the access to the same outer variables.
220220

221221
An example with the constructor function (see the chapter <info:constructor-new>):
222222

223223
```js run
224224
// constructor function returns a new object
225225
function User(name) {
226226

227-
// the method is created as a nested function
227+
// the object method is created as a nested function
228228
this.sayHi = function() {
229229
alert(name);
230230
};
231231
}
232232

233233
let user = new User("John");
234-
user.sayHi();
234+
user.sayHi(); // the method code has access to the outer "name"
235235
```
236236

237237
An example with returning a function:
@@ -241,7 +241,7 @@ function makeCounter() {
241241
let count = 0;
242242

243243
return function() {
244-
return count++;
244+
return count++; // has access to the outer counter
245245
};
246246
}
247247

@@ -252,13 +252,11 @@ alert( counter() ); // 1
252252
alert( counter() ); // 2
253253
```
254254

255-
Let's go on with the `makeCounter` example. It creates the "counter" function that returns the next number on each invocation. Despite being simple, slightly modified variants of that code have practical uses, for instance, as a [pseudorandom number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator), and more. So the example is not exactly "artificial".
256-
257-
How does the counter work?
255+
Let's go on with the `makeCounter` example. It creates the "counter" function that returns the next number on each invocation. Despite being simple, slightly modified variants of that code have practical uses, for instance, as a [pseudorandom number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator), and more. So the example is not quite artificial.
258256

259-
When the inner function runs, the variable in `count++` is searched from inside out.
257+
How does the counter work internally?
260258

261-
For the example above, the order will be:
259+
When the inner function runs, the variable in `count++` is searched from inside out. For the example above, the order will be:
262260

263261
![](lexical-search-order.png)
264262

@@ -268,7 +266,7 @@ For the example above, the order will be:
268266

269267
In that example `count` is found on the step `2`. When an outer variable is modified, it's changed where it's found. So `count++` finds the outer variable and increases it in the Lexical Environment where it belongs. Like if we had `let count = 1`.
270268

271-
Here's a couple of questions:
269+
Here are two questions for you:
272270

273271
1. Can we somehow reset the `counter` from the code that doesn't belong to `makeCounter`? E.g. after `alert` calls in the example above.
274272
2. If we call `makeCounter()` multiple times -- it returns many `counter` functions. Are they independent or do they share the same `count`?
@@ -302,11 +300,13 @@ alert( counter2() ); // 0 (independant)
302300
```
303301

304302

305-
Probably, the situation with outer variables is quite clear for you as of now. But in more complex situations a deeper understanding of internals may be required. So here you go.
303+
Probably, the situation with outer variables is quite clear for you as of now. But in more complex situations a deeper understanding of internals may be required. So let's go ahead.
306304

307305
## Environments in detail
308306

309-
For a more in-depth understanding, here's what's going on in the `makeCounter` example step-by-step, down to the nuts and bolts:
307+
Now as you understand how closures work generally, we may finally descend to the very nuts and bolts.
308+
309+
Here's what's going on in the `makeCounter` example step-by-step, follow it to make sure that you understand everything. Please note the additional `[[Environment]]` property that we didn't cover yet.
310310

311311
1. When the script has just started, there is only global Lexical Environment:
312312

@@ -318,6 +318,8 @@ For a more in-depth understanding, here's what's going on in the `makeCounter` e
318318

319319
Here, `makeCounter` is created in the global Lexical Environment, so `[[Environment]]` keeps the reference to it.
320320

321+
In other words, a function is "imprinted" with a reference to the Lexical Environment where it was born. And `[[Environment]]` is the hidden function property that has that reference.
322+
321323
2. Then the code runs on, and the call to `makeCounter()` is performed. Here's the picture for the moment when the execution is on the first line inside `makeCounter()`:
322324

323325
![](lexenv-nested-makecounter-2.png)

0 commit comments

Comments
 (0)