Skip to content

Commit 510dd09

Browse files
author
root
committed
Merge branch 'master' of github.com:javascript-tutorial/en.javascript.info into sync-a0266c57
2 parents d7b0120 + a0266c5 commit 510dd09

File tree

24 files changed

+83
-76
lines changed

24 files changed

+83
-76
lines changed

1-js/04-object-basics/02-garbage-collection/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,6 @@ A general book "The Garbage Collection Handbook: The Art of Automatic Memory Man
207207

208208
If you are familiar with low-level programming, the more detailed information about V8 garbage collector is in the article [A tour of V8: Garbage Collection](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
209209

210-
[V8 blog](http://v8project.blogspot.com/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
210+
[V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
211211

212212
In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.

1-js/04-object-basics/04-object-methods/article.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ user.sayHi(); // Hello!
6363
```smart header="Object-oriented programming"
6464
When we write our code using objects to represent entities, that's called an [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP".
6565
66-
OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, and more.
66+
OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, and more.
6767
```
6868
### Method shorthand
6969

@@ -72,14 +72,14 @@ There exists a shorter syntax for methods in an object literal:
7272
```js
7373
// these objects do the same
7474

75-
let user = {
75+
user = {
7676
sayHi: function() {
7777
alert("Hello");
7878
}
7979
};
8080

8181
// method shorthand looks better, right?
82-
let user = {
82+
user = {
8383
*!*
8484
sayHi() { // same as "sayHi: function()"
8585
*/!*
@@ -166,7 +166,7 @@ If we used `this.name` instead of `user.name` inside the `alert`, then the code
166166

167167
## "this" is not bound
168168

169-
In JavaScript, "this" keyword behaves unlike most other programming languages. First, it can be used in any function.
169+
In JavaScript, "this" keyword behaves unlike most other programming languages. It can be used in any function.
170170

171171
There's no syntax error in the code like that:
172172

@@ -176,9 +176,9 @@ function sayHi() {
176176
}
177177
```
178178

179-
The value of `this` is evaluated during the run-time. And it can be anything.
179+
The value of `this` is evaluated during the run-time, depending on the context. And it can be anything.
180180

181-
For instance, the same function may have different "this" when called from different objects:
181+
For instance, here the same function is assigned to two different objects and has different "this" in the calls:
182182

183183
```js run
184184
let user = { name: "John" };
@@ -189,7 +189,7 @@ function sayHi() {
189189
}
190190

191191
*!*
192-
// use the same functions in two objects
192+
// use the same function in two objects
193193
user.f = sayHi;
194194
admin.f = sayHi;
195195
*/!*
@@ -202,7 +202,10 @@ admin.f(); // Admin (this == admin)
202202
admin['f'](); // Admin (dot or square brackets access the method – doesn't matter)
203203
```
204204

205-
Actually, we can call the function without an object at all:
205+
The rule is simple: if `obj.f()` is called, then `this` is `obj` during the call of `f`. So it's either `user` or `admin` in the example above.
206+
207+
````smart header="Calling without an object: `this == undefined`"
208+
We can even call the function without an object at all:
206209

207210
```js run
208211
function sayHi() {
@@ -216,7 +219,8 @@ In this case `this` is `undefined` in strict mode. If we try to access `this.nam
216219

217220
In non-strict mode the value of `this` in such case will be the *global object* (`window` in a browser, we'll get to it later in the chapter [](info:global-object)). This is a historical behavior that `"use strict"` fixes.
218221

219-
Please note that usually a call of a function that uses `this` without an object is not normal, but rather a programming mistake. If a function has `this`, then it is usually meant to be called in the context of an object.
222+
Usually such call is an programming error. If there's `this` inside a function, it expects to be called in an object context.
223+
````
220224
221225
```smart header="The consequences of unbound `this`"
222226
If you come from another programming language, then you are probably used to the idea of a "bound `this`", where methods defined in an object always have `this` referencing that object.

1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe("readNumber", function() {
1818
assert.strictEqual(readNumber(), 0);
1919
});
2020

21-
it("continues the loop unti meets a number", function() {
21+
it("continues the loop until meets a number", function() {
2222
prompt.onCall(0).returns("not a number");
2323
prompt.onCall(1).returns("not a number again");
2424
prompt.onCall(2).returns("1");
@@ -35,4 +35,4 @@ describe("readNumber", function() {
3535
assert.isNull(readNumber());
3636
});
3737

38-
});
38+
});

1-js/05-data-types/11-json/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ alert(json);
6666

6767
The method `JSON.stringify(student)` takes the object and converts it into a string.
6868

69-
The resulting `json` string is a called *JSON-encoded* or *serialized* or *stringified* or *marshalled* object. We are ready to send it over the wire or put into a plain data store.
69+
The resulting `json` string is called a *JSON-encoded* or *serialized* or *stringified* or *marshalled* object. We are ready to send it over the wire or put into a plain data store.
7070

7171

7272
Please note that a JSON-encoded object has several important differences from the object literal:

1-js/08-prototypes/02-function-prototype/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Everything is quite simple, just few notes to make things clear:
162162

163163
- The `F.prototype` property is not the same as `[[Prototype]]`. The only thing `F.prototype` does: it sets `[[Prototype]]` of new objects when `new F()` is called.
164164
- The value of `F.prototype` should be either an object or null: other values won't work.
165-
- The `"prototype"` property only has such a special effect when is set to a constructor function, and invoked with `new`.
165+
- The `"prototype"` property only has such a special effect when set on a constructor function, and invoked with `new`.
166166

167167
On regular objects the `prototype` is nothing special:
168168
```js

1-js/09-classes/01-class/article.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ The notation here is not to be confused with object literals. Within the class,
6464

6565
## What is a class?
6666

67-
So, what exactly is a `class`? That's not an entirely new language-level entity, as one might think.
67+
So, what exactly is a `class`? That's not an entirely new language-level entity, as one might think.
6868

6969
Let's unveil any magic and see what a class really is. That'll help in understanding many complex aspects.
7070

@@ -91,7 +91,7 @@ What `class User {...}` construct really does is:
9191

9292
Afterwards, for new objects, when we call a method, it's taken from the prototype, just as described in the chapter <info:function-prototype>. So `new User` object has access to class methods.
9393

94-
We can illustrate the result of `class User` as:
94+
We can illustrate the result of `class User` declaration as:
9595

9696
![](class-user.png)
9797

@@ -198,7 +198,8 @@ Similar to Named Function Expressions, class expressions may or may not have a n
198198
If a class expression has a name, it's visible inside the class only:
199199
200200
```js run
201-
// "Named Class Expression" (alas, no such term, but that's what's going on)
201+
// "Named Class Expression"
202+
// (no such term in the spec, but that's similar to Named Function Expression)
202203
let User = class *!*MyClass*/!* {
203204
sayHi() {
204205
alert(MyClass); // MyClass is visible only inside the class
@@ -268,7 +269,7 @@ alert(user.name); // John
268269
user = new User(""); // Name too short.
269270
```
270271

271-
Internally, getters and setters are created on `User.prototype`, like this:
272+
The class declaration creates getters and setters in `User.prototype`, like this:
272273

273274
```js
274275
Object.defineProperties(User.prototype, {

1-js/10-error-handling/2-custom-errors/article.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Our errors should support basic error properties like `message`, `name` and, pre
66

77
JavaScript allows to use `throw` with any argument, so technically our custom error classes don't need to inherit from `Error`. But if we inherit, then it becomes possible to use `obj instanceof Error` to identify error objects. So it's better to inherit from it.
88

9-
As we build our application, our own errors naturally form a hierarchy, for instance `HttpTimeoutError` may inherit from `HttpError`, and so on.
9+
As the application grows, our own errors naturally form a hierarchy, for instance `HttpTimeoutError` may inherit from `HttpError`, and so on.
1010

1111
## Extending Error
1212

@@ -126,7 +126,7 @@ We could also look at `err.name`, like this:
126126
127127
The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.
128128
129-
Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or such) should fall through.
129+
Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or other unknown ones) should fall through.
130130
131131
## Further inheritance
132132
@@ -185,7 +185,7 @@ try {
185185
186186
The new class `PropertyRequiredError` is easy to use: we only need to pass the property name: `new PropertyRequiredError(property)`. The human-readable `message` is generated by the constructor.
187187
188-
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = <class name>` when creating each custom error. But there's a way out. We can make our own "basic error" class that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in the constructor. And then inherit from it.
188+
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = <class name>` in every custom error class. But there's a way out. We can make our own "basic error" class that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in its constructor. And then inherit all ours custom errors from it.
189189
190190
Let's call it `MyError`.
191191
@@ -218,7 +218,7 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid
218218
219219
## Wrapping exceptions
220220
221-
The purpose of the function `readUser` in the code above is "to read the user data", right? There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow: the new code will probably generate other kinds of errors.
221+
The purpose of the function `readUser` in the code above is "to read the user data", right? There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow and probably generate other kinds of errors.
222222
223223
The code which calls `readUser` should handle these errors. Right now it uses multiple `if` in the `catch` block to check for different error types and rethrow the unknown ones. But if `readUser` function generates several kinds of errors -- then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls `readUser`?
224224
@@ -303,5 +303,5 @@ The approach is called "wrapping exceptions", because we take "low level excepti
303303
## Summary
304304
305305
- We can inherit from `Error` and other built-in error classes normally, just need to take care of `name` property and don't forget to call `super`.
306-
- Most of the time, we should use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name` property can be used for such checks.
307-
- Wrapping exceptions is a widespread technique when a function handles low-level exceptions and makes a higher-level object to report about the errors. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required.
306+
- We can use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name` property can be used for such checks.
307+
- Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required.

1-js/11-async/07-microtask-queue/article.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
Promise handlers `.then`/`.catch`/`.finally` are always asynchronous.
55

6-
Even when a Promise is immediately resolved, the code on the lines *below* your `.then`/`.catch`/`.finally` will still execute first.
6+
Even when a Promise is immediately resolved, the code on the lines *below* `.then`/`.catch`/`.finally` will still execute before these handlers .
77

8-
Here's the code that demonstrates it:
8+
Here's the demo:
99

1010
```js run
1111
let promise = Promise.resolve();
@@ -21,7 +21,7 @@ That's strange, because the promise is definitely done from the beginning.
2121

2222
Why did the `.then` trigger afterwards? What's going on?
2323

24-
# Microtasks
24+
## Microtasks
2525

2626
Asynchronous tasks need proper management. For that, the standard specifies an internal queue `PromiseJobs`, more often referred to as "microtask queue" (v8 term).
2727

@@ -54,9 +54,11 @@ Now the order is as intended.
5454

5555
## Event loop
5656

57-
In-browser JavaScript, as well as Node.js, is based on an *event loop*.
57+
In-browser JavaScript execution flow, as well as Node.js, is based on an *event loop*.
5858

59-
"Event loop" is a process when the engine sleeps and waits for events, then reacts on those and sleeps again.
59+
"Event loop" is a process when the engine sleeps and waits for events. When they occur - handles them and sleeps again.
60+
61+
Events may come either comes from external sources, like user actions, or just as the end signal of an internal task.
6062

6163
Examples of events:
6264
- `mousemove`, a user moved their mouse.
@@ -120,14 +122,14 @@ Promise.resolve()
120122

121123
Naturally, `promise` shows up first, because `setTimeout` macrotask awaits in the less-priority macrotask queue.
122124

123-
As a logical consequence, macrotasks are handled only when promises give the engine a "free time". So if we have a promise chain that doesn't wait for anything, then things like `setTimeout` or event handlers can never get in the middle.
125+
As a logical consequence, macrotasks are handled only when promises give the engine a "free time". So if we have a chain of promise handlers that don't wait for anything, execute right one after another, then a `setTimeout` (or a user action handler) can never run in-between them.
124126

125127

126128
## Unhandled rejection
127129

128130
Remember "unhandled rejection" event from the chapter <info:promise-error-handling>?
129131

130-
Now, with the understanding of microtasks, we can formalize it.
132+
Now we can describe how JavaScript finds out that a rejection was not handled.
131133

132134
**"Unhandled rejection" is when a promise error is not handled at the end of the microtask queue.**
133135

@@ -167,15 +169,15 @@ setTimeout(() => promise.catch(err => alert('caught')));
167169
window.addEventListener('unhandledrejection', event => alert(event.reason));
168170
```
169171

170-
Now the unhandled rejection appears again. Why? Because `unhandledrejection` triggers when the microtask queue is complete. The engine examines promises and, if any of them is in "rejected" state, then the event is generated.
172+
Now the unhandled rejection appears again. Why? Because `unhandledrejection` is generated when the microtask queue is complete. The engine examines promises and, if any of them is in "rejected" state, then the event triggers.
171173

172174
In the example, the `.catch` added by `setTimeout` triggers too, of course it does, but later, after `unhandledrejection` has already occurred.
173175

174176
## Summary
175177

176178
- Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term).
177179

178-
**So, `.then/catch/finally` are called after the current code is finished.**
180+
**So, `.then/catch/finally` handlers are called after the current code is finished.**
179181

180182
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, it's best to add it into a chained `.then` call.
181183

1-js/13-modules/03-modules-dynamic-imports/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
# Dynamic imports
33

4-
Export and import statements that we covered in previous chaters are called "static".
4+
Export and import statements that we covered in previous chapters are called "static".
55

66
That's because they are indeed static. The syntax is very strict.
77

2-ui/1-document/05-basic-dom-node-properties/2-tree-info/solution.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ for (let li of document.querySelectorAll('li')) {
66
}
77
```
88

9-
In the loop we need to get the text inside every `li`. We can read it directly from the first child node, that is the text node:
9+
In the loop we need to get the text inside every `li`.
10+
11+
We can read the text from the first child node of `li`, that is the text node:
1012

1113
```js
1214
for (let li of document.querySelectorAll('li')) {
@@ -16,4 +18,4 @@ for (let li of document.querySelectorAll('li')) {
1618
}
1719
```
1820

19-
Then we can get the number of descendants `li.getElementsByTagName('li')`.
21+
Then we can get the number of descendants as `li.getElementsByTagName('li').length`.

0 commit comments

Comments
 (0)