Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f518b9c

Browse files
authoredNov 11, 2019
Merge pull request #2 from javascript-tutorial/sync-2b5ac971
Sync with upstream @ 2b5ac97
2 parents 4857dd3 + b5680b1 commit f518b9c

File tree

31 files changed

+232
-202
lines changed

31 files changed

+232
-202
lines changed
 

‎1-js/01-getting-started/1-intro/article.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ Varikliai yra sudėtingi daiktai, bet basic'ai yra paprasti.
3838
2. Konvertuoja ("kompiliuoja") skriptą į mašininį kodą.
3939
3. Vykdomas mašininis kodas.
4040
41+
<<<<<<< HEAD
4142
Varikliai optimizuoja kodą kiekviename žingsnyje. Jie netgi stebi sukompiliuotą skriptą, kuomet jis vykdomas, bei analizuoja duomenis, kurie jame naudojami, ir pagal tai taiko papildomas optimizacijas. Po viso šio procesio, skriptai yra vykdomi gan greitai.
43+
=======
44+
The engine applies optimizations at each step of the process. It even watches the compiled script as it runs, analyzes the data that flows through it, and further optimizes the machine code based on that knowledge.
45+
>>>>>>> 2b5ac971c1bd8abe7b17cdcf724afd84799b6cbd
4246
```
4347

4448
## Ką gali JavaScript'as padaryti naršyklėje?

‎1-js/02-first-steps/15-function-expressions-arrows/article.md renamed to ‎1-js/02-first-steps/15-function-expressions/article.md

Lines changed: 1 addition & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Function expressions and arrows
1+
# Function expressions
22

33
In JavaScript, a function is not a "magical language structure", but a special kind of value.
44

@@ -355,107 +355,6 @@ That's also better for readability, as it's easier to look up `function f(…) {
355355
...But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we've just seen an example), then Function Expression should be used.
356356
```
357357

358-
359-
## Arrow functions [#arrow-functions]
360-
361-
There's one more very simple and concise syntax for creating functions, that's often better than Function Expressions. It's called "arrow functions", because it looks like this:
362-
363-
364-
```js
365-
let func = (arg1, arg2, ...argN) => expression
366-
```
367-
368-
...This creates a function `func` that has arguments `arg1..argN`, evaluates the `expression` on the right side with their use and returns its result.
369-
370-
In other words, it's roughly the same as:
371-
372-
```js
373-
let func = function(arg1, arg2, ...argN) {
374-
return expression;
375-
};
376-
```
377-
378-
...But much more concise.
379-
380-
Let's see an example:
381-
382-
```js run
383-
let sum = (a, b) => a + b;
384-
385-
/* The arrow function is a shorter form of:
386-
387-
let sum = function(a, b) {
388-
return a + b;
389-
};
390-
*/
391-
392-
alert( sum(1, 2) ); // 3
393-
394-
```
395-
396-
If we have only one argument, then parentheses around parameters can be omitted, making that even shorter:
397-
398-
```js run
399-
// same as
400-
// let double = function(n) { return n * 2 }
401-
*!*
402-
let double = n => n * 2;
403-
*/!*
404-
405-
alert( double(3) ); // 6
406-
```
407-
408-
If there are no arguments, parentheses should be empty (but they should be present):
409-
410-
```js run
411-
let sayHi = () => alert("Hello!");
412-
413-
sayHi();
414-
```
415-
416-
Arrow functions can be used in the same way as Function Expressions.
417-
418-
For instance, here's the rewritten example with `welcome()`:
419-
420-
```js run
421-
let age = prompt("What is your age?", 18);
422-
423-
let welcome = (age < 18) ?
424-
() => alert('Hello') :
425-
() => alert("Greetings!");
426-
427-
welcome(); // ok now
428-
```
429-
430-
Arrow functions may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure.
431-
432-
They are very convenient for simple one-line actions, when we're just too lazy to write many words.
433-
434-
```smart header="Multiline arrow functions"
435-
436-
The examples above took arguments from the left of `=>` and evaluated the right-side expression with them.
437-
438-
Sometimes we need something a little bit more complex, like multiple expressions or statements. It is also possible, but we should enclose them in curly braces. Then use a normal `return` within them.
439-
440-
Like this:
441-
442-
```js run
443-
let sum = (a, b) => { // the curly brace opens a multiline function
444-
let result = a + b;
445-
*!*
446-
return result; // if we use curly braces, use return to get results
447-
*/!*
448-
};
449-
450-
alert( sum(1, 2) ); // 3
451-
```
452-
453-
```smart header="More to come"
454-
Here we praised arrow functions for brevity. But that's not all! Arrow functions have other interesting features. We'll return to them later in the chapter <info:arrow-functions>.
455-
456-
For now, we can already use arrow functions for one-line actions and callbacks.
457-
```
458-
459358
## Summary
460359

461360
- Functions are values. They can be assigned, copied or declared in any place of the code.
@@ -467,8 +366,3 @@ For now, we can already use arrow functions for one-line actions and callbacks.
467366
In most cases when we need to declare a function, a Function Declaration is preferable, because it is visible prior to the declaration itself. That gives us more flexibility in code organization, and is usually more readable.
468367

469368
So we should use a Function Expression only when a Function Declaration is not fit for the task. We've seen a couple of examples of that in this chapter, and will see more in the future.
470-
471-
Arrow functions are handy for one-liners. They come in two flavors:
472-
473-
1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result.
474-
2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something.

‎1-js/02-first-steps/15-function-expressions-arrows/1-rewrite-arrow/task.md renamed to ‎1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/task.md

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

22
# Rewrite with arrow functions
33

4-
Replace Function Expressions with arrow functions in the code:
4+
Replace Function Expressions with arrow functions in the code below:
55

66
```js run
77
function ask(question, yes, no) {
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Arrow functions, the basics
2+
3+
There's another very simple and concise syntax for creating functions, that's often better than Function Expressions.
4+
5+
It's called "arrow functions", because it looks like this:
6+
7+
```js
8+
let func = (arg1, arg2, ...argN) => expression
9+
```
10+
11+
...This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result.
12+
13+
In other words, it's the shorter version of:
14+
15+
```js
16+
let func = function(arg1, arg2, ...argN) {
17+
return expression;
18+
};
19+
```
20+
21+
Let's see a concrete example:
22+
23+
```js run
24+
let sum = (a, b) => a + b;
25+
26+
/* This arrow function is a shorter form of:
27+
28+
let sum = function(a, b) {
29+
return a + b;
30+
};
31+
*/
32+
33+
alert( sum(1, 2) ); // 3
34+
```
35+
36+
As you can, see `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result.
37+
38+
- If we have only one argument, then parentheses around parameters can be omitted, making that even shorter.
39+
40+
For example:
41+
42+
```js run
43+
*!*
44+
let double = n => n * 2;
45+
// roughly the same as: let double = function(n) { return n * 2 }
46+
*/!*
47+
48+
alert( double(3) ); // 6
49+
```
50+
51+
- If there are no arguments, parentheses will be empty (but they should be present):
52+
53+
```js run
54+
let sayHi = () => alert("Hello!");
55+
56+
sayHi();
57+
```
58+
59+
Arrow functions can be used in the same way as Function Expressions.
60+
61+
For instance, to dynamically create a function:
62+
63+
```js run
64+
let age = prompt("What is your age?", 18);
65+
66+
let welcome = (age < 18) ?
67+
() => alert('Hello') :
68+
() => alert("Greetings!");
69+
70+
welcome(); // ok now
71+
```
72+
73+
Arrow functions may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure.
74+
75+
They are very convenient for simple one-line actions, when we're just too lazy to write many words.
76+
77+
## Multiline arrow functions
78+
79+
The examples above took arguments from the left of `=>` and evaluated the right-side expression with them.
80+
81+
Sometimes we need something a little bit more complex, like multiple expressions or statements. It is also possible, but we should enclose them in curly braces. Then use a normal `return` within them.
82+
83+
Like this:
84+
85+
```js run
86+
let sum = (a, b) => { // the curly brace opens a multiline function
87+
let result = a + b;
88+
*!*
89+
return result; // if we use curly braces, then we need an explicit "return"
90+
*/!*
91+
};
92+
93+
alert( sum(1, 2) ); // 3
94+
```
95+
96+
```smart header="More to come"
97+
Here we praised arrow functions for brevity. But that's not all!
98+
99+
Arrow functions have other interesting features.
100+
101+
To study them in-depth, we first need to get to know some other aspects of JavaScript, so we'll return to arrow functions later in the chapter <info:arrow-functions>.
102+
103+
For now, we can already use arrow functions for one-line actions and callbacks.
104+
```
105+
106+
## Summary
107+
108+
Arrow functions are handy for one-liners. They come in two flavors:
109+
110+
1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result.
111+
2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something.

‎1-js/02-first-steps/16-javascript-specials/article.md renamed to ‎1-js/02-first-steps/17-javascript-specials/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ We covered three ways to create a function in JavaScript:
272272
- Parameters can have default values: `function sum(a = 1, b = 2) {...}`.
273273
- Functions always return something. If there's no `return` statement, then the result is `undefined`.
274274
275-
Details: see <info:function-basics>, <info:function-expressions-arrows>.
275+
Details: see <info:function-basics>, <info:arrow-functions-basics>.
276276
277277
## More to come
278278

‎1-js/04-object-basics/05-object-toprimitive/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ These methods must return a primitive value. If `toString` or `valueOf` returns
123123
By default, a plain object has following `toString` and `valueOf` methods:
124124

125125
- The `toString` method returns a string `"[object Object]"`.
126-
- The `valueOf` method returns an object itself.
126+
- The `valueOf` method returns the object itself.
127127

128128
Here's the demo:
129129

@@ -199,7 +199,7 @@ In contrast, `Symbol.toPrimitive` *must* return a primitive, otherwise there wil
199199

200200
## Further conversions
201201

202-
As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operatnds to numbers.
202+
As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operands to numbers.
203203

204204
If we pass an object as an argument, then there are two stages:
205205
1. The object is converted to a primitive (using the rules described above).

‎1-js/05-data-types/05-array-methods/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ alert(arr); // *!*1, 2, 15*/!*
447447
````
448448

449449
````smart header="Arrow functions for the best"
450-
Remember [arrow functions](info:function-expressions-arrows#arrow-functions)? We can use them here for neater sorting:
450+
Remember [arrow functions](info:arrow-functions-basics)? We can use them here for neater sorting:
451451
452452
```js
453453
arr.sort( (a, b) => a - b );

‎1-js/05-data-types/06-iterable/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ let arr = Array.from(arrayLike); // (*)
214214
alert(arr.pop()); // World (method works)
215215
```
216216

217-
`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies there all items.
217+
`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies all items to it.
218218

219219
The same happens for an iterable:
220220

‎1-js/05-data-types/11-date/article.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ To create a new `Date` object call `new Date()` with one of the following argume
3333

3434
It's a lightweight numeric representation of a date. We can always create a date from a timestamp using `new Date(timestamp)` and convert the existing `Date` object to a timestamp using the `date.getTime()` method (see below).
3535

36+
Dates before 01.01.1970 have negative timestamps, e.g.:
37+
```js run
38+
// 31 Dec 1969
39+
let Dec31_1969 = new Date(-24 * 3600 * 1000);
40+
alert( Dec31_1969 );
41+
```
42+
3643
`new Date(datestring)`
3744
: If there is a single argument, and it's a string, then it is parsed automatically. The algorithm is the same as `Date.parse` uses, we'll cover it later.
3845

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ alert(User.prototype.sayHi); // alert(this.name);
116116
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
117117
```
118118

119-
## Not just a syntax sugar
119+
## Not just a syntactic sugar
120120

121-
Sometimes people say that `class` is a "syntax sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all:
121+
Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all:
122122

123123
```js run
124124
// rewriting class User in pure functions
@@ -140,7 +140,7 @@ let user = new User("John");
140140
user.sayHi();
141141
```
142142

143-
The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntax sugar to define a constructor together with its prototype methods.
143+
The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntactic sugar to define a constructor together with its prototype methods.
144144

145145
Still, there are important differences.
146146

@@ -282,7 +282,7 @@ Object.defineProperties(User.prototype, {
282282
});
283283
```
284284

285-
Here's an example with a computed property in brackets `[...]`:
285+
Here's an example with a computed property name in brackets `[...]`:
286286

287287
```js run
288288
class User {
@@ -318,6 +318,9 @@ class User {
318318
}
319319

320320
new User().sayHi();
321+
322+
alert(User.prototype.sayHi); // placed in User.prototype
323+
alert(User.prototype.name); // undefined, not placed in User.prototype
321324
```
322325

323326
The property `name` is not placed into `User.prototype`. Instead, it is created by `new` before calling the constructor, it's a property of the object itself.

‎1-js/09-classes/02-class-inheritance/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The syntax to extend another class is: `class Child extends Parent`.
4040

4141
Let's create `class Rabbit` that inherits from `Animal`:
4242

43-
```js run
43+
```js
4444
*!*
4545
class Rabbit extends Animal {
4646
*/!*

‎1-js/09-classes/03-static-properties-methods/article.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ User.staticMethod(); // true
1919

2020
That actually does the same as assigning it as a property directly:
2121

22-
```js
22+
```js run
2323
class User() { }
2424

2525
User.staticMethod = function() {
2626
alert(this === User);
2727
};
28+
29+
User.staticMethod(); // true
2830
```
2931

3032
The value of `this` in `User.staticMethod()` call is the class constructor `User` itself (the "object before dot" rule).
@@ -123,14 +125,15 @@ That is the same as a direct assignment to `Article`:
123125
Article.publisher = "Ilya Kantor";
124126
```
125127

126-
## Inheritance of static methods
128+
## Inheritance of static properties and methods
127129

128-
Static methods are inherited.
130+
Static properties and methods are inherited.
129131

130-
For instance, `Animal.compare` in the code below is inherited and accessible as `Rabbit.compare`:
132+
For instance, `Animal.compare` and `Animal.planet` in the code below are inherited and accessible as `Rabbit.compare` and `Rabbit.planet`:
131133

132134
```js run
133135
class Animal {
136+
static planet = "Earth";
134137

135138
constructor(name, speed) {
136139
this.speed = speed;
@@ -167,6 +170,8 @@ rabbits.sort(Rabbit.compare);
167170
*/!*
168171

169172
rabbits[0].run(); // Black Rabbit runs with speed 5.
173+
174+
alert(Rabbit.planet); // Earth
170175
```
171176

172177
Now when we call `Rabbit.compare`, the inherited `Animal.compare` will be called.

‎1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/task.md

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

44
There are many areas where we need random data.
55

6-
One of them is testing. We may need random data: text, numbers etc, to test things out well.
6+
One of them is testing. We may need random data: text, numbers, etc. to test things out well.
77

88
In JavaScript, we could use `Math.random()`. But if something goes wrong, we'd like to be able to repeat the test, using exactly the same data.
99

10-
For that, so called "seeded pseudo-random generators" are used. They take a "seed", the first value, and then generate next ones using a formula. So that the same seed yields the same sequence, and hence the whole flow is easily reproducible. We only need to remember the seed to repeat it.
10+
For that, so called "seeded pseudo-random generators" are used. They take a "seed", the first value, and then generate the next ones using a formula so that the same seed yields the same sequence, and hence the whole flow is easily reproducible. We only need to remember the seed to repeat it.
1111

1212
An example of such formula, that generates somewhat uniformly distributed values:
1313

‎1-js/12-generators-iterators/1-generators/article.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The function code execution hasn't started yet:
4040

4141
![](generateSequence-1.svg)
4242

43-
The main method of a generator is `next()`. When called, it runs the execution till the nearest `yield <value>` statement (`value` can be omitted, then it's `undefined`). Then the function execution pauses, and the yielded `value` is returned to the outer code.
43+
The main method of a generator is `next()`. When called, it runs the execution until the nearest `yield <value>` statement (`value` can be omitted, then it's `undefined`). Then the function execution pauses, and the yielded `value` is returned to the outer code.
4444

4545
The result of `next()` is always an object with two properties:
4646
- `value`: the yielded value.
@@ -78,7 +78,7 @@ alert(JSON.stringify(two)); // {value: 2, done: false}
7878

7979
![](generateSequence-3.svg)
8080

81-
And, if we call it the third time, then the execution reaches `return` statement that finishes the function:
81+
And, if we call it a third time, the execution reaches the `return` statement that finishes the function:
8282

8383
```js
8484
let three = generator.next();
@@ -90,7 +90,7 @@ alert(JSON.stringify(three)); // {value: 3, *!*done: true*/!*}
9090

9191
Now the generator is done. We should see it from `done:true` and process `value:3` as the final result.
9292

93-
New calls `generator.next()` don't make sense any more. If we do them, they return the same object: `{done: true}`.
93+
New calls to `generator.next()` don't make sense any more. If we do them, they return the same object: `{done: true}`.
9494

9595
```smart header="`function* f(…)` or `function *f(…)`?"
9696
Both syntaxes are correct.
@@ -154,7 +154,7 @@ let sequence = [0, ...generateSequence()];
154154
alert(sequence); // 0, 1, 2, 3
155155
```
156156

157-
In the code above, `...generateSequence()` turns the iterable generator object into array of items (read more about the spread operator in the chapter [](info:rest-parameters-spread-operator#spread-operator))
157+
In the code above, `...generateSequence()` turns the iterable generator object into an array of items (read more about the spread operator in the chapter [](info:rest-parameters-spread-operator#spread-operator))
158158

159159
## Using generators for iterables
160160

@@ -212,17 +212,17 @@ alert( [...range] ); // 1,2,3,4,5
212212
```
213213

214214
That works, because `range[Symbol.iterator]()` now returns a generator, and generator methods are exactly what `for..of` expects:
215-
- it has `.next()` method
215+
- it has a `.next()` method
216216
- that returns values in the form `{value: ..., done: true/false}`
217217

218-
That's not a coincidence, of course. Generators were added to JavaScript language with iterators in mind, to implement them easier.
218+
That's not a coincidence, of course. Generators were added to JavaScript language with iterators in mind, to implement them easily.
219219

220220
The variant with a generator is much more concise than the original iterable code of `range`, and keeps the same functionality.
221221

222222
```smart header="Generators may generate values forever"
223223
In the examples above we generated finite sequences, but we can also make a generator that yields values forever. For instance, an unending sequence of pseudo-random numbers.
224224
225-
That surely would require a `break` (or `return`) in `for..of` over such generator, otherwise the loop would repeat forever and hang.
225+
That surely would require a `break` (or `return`) in `for..of` over such generator. Otherwise, the loop would repeat forever and hang.
226226
```
227227

228228
## Generator composition
@@ -237,7 +237,7 @@ function* generateSequence(start, end) {
237237
}
238238
```
239239

240-
Now we'd like to reuse it for generation of a more complex sequence:
240+
Now we'd like to reuse it to generate a more complex sequence:
241241
- first, digits `0..9` (with character codes 48..57),
242242
- followed by uppercase alphabet letters `A..Z` (character codes 65..90)
243243
- followed by lowercase alphabet letters `a..z` (character codes 97..122)
@@ -316,7 +316,7 @@ A generator composition is a natural way to insert a flow of one generator into
316316

317317
## "yield" is a two-way road
318318

319-
Till this moment, generators were similar to iterable objects, with a special syntax to generate values. But in fact they are much more powerful and flexible.
319+
Until this moment, generators were similar to iterable objects, with a special syntax to generate values. But in fact they are much more powerful and flexible.
320320

321321
That's because `yield` is a two-way road: it not only returns the result outside, but also can pass the value inside the generator.
322322

@@ -422,7 +422,7 @@ generator.throw(new Error("The answer is not found in my database")); // (2)
422422
*/!*
423423
```
424424

425-
The error, thrown into the generator at the line `(2)` leads to an exception in the line `(1)` with `yield`. In the example above, `try..catch` catches it and shows.
425+
The error, thrown into the generator at line `(2)` leads to an exception in line `(1)` with `yield`. In the example above, `try..catch` catches it and shows it.
426426

427427
If we don't catch it, then just like any exception, it "falls out" the generator into the calling code.
428428

@@ -456,6 +456,6 @@ If we don't catch the error there, then, as usual, it falls through to the outer
456456

457457
In modern JavaScript, generators are rarely used. But sometimes they come in handy, because the ability of a function to exchange data with the calling code during the execution is quite unique. And, surely, they are great for making iterable objects.
458458

459-
Also, in the next chapter we'll learn async generators, which are used to read streams of asynchronously generated data (e.g paginated fetches over a network) in `for await ... of` loop.
459+
Also, in the next chapter we'll learn async generators, which are used to read streams of asynchronously generated data (e.g paginated fetches over a network) in `for await ... of` loops.
460460

461461
In web-programming we often work with streamed data, so that's another very important use case.

‎1-js/12-generators-iterators/2-async-iterators-generators/article.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Let's see a simple example first, to grasp the syntax, and then review a real-li
99

1010
Asynchronous iterators are similar to regular iterators, with a few syntactic differences.
1111

12-
"Regular" iterable object, as described in the chapter <info:iterable>, look like this:
12+
A "regular" iterable object, as described in the chapter <info:iterable>, looks like this:
1313

1414
```js run
1515
let range = {
@@ -79,8 +79,10 @@ let range = {
7979
// (automatically wrapped into a promise by async)
8080
*/!*
8181

82+
*!*
8283
// can use await inside, do async stuff:
8384
await new Promise(resolve => setTimeout(resolve, 1000)); // (3)
85+
*/!*
8486

8587
if (this.current <= this.last) {
8688
return { done: false, value: this.current++ };
@@ -267,7 +269,7 @@ So far we've seen simple examples, to gain basic understanding. Now let's review
267269
268270
There are many online services that deliver paginated data. For instance, when we need a list of users, a request returns a pre-defined count (e.g. 100 users) - "one page", and provides a URL to the next page.
269271
270-
The pattern is very common, it's not about users, but just about anything. For instance, GitHub allows to retrieve commits in the same, paginated fashion:
272+
This pattern is very common. It's not about users, but just about anything. For instance, GitHub allows to retrieve commits in the same, paginated fashion:
271273
272274
- We should make a request to URL in the form `https://api.github.com/repos/<repo>/commits`.
273275
- It responds with a JSON of 30 commits, and also provides a link to the next page in the `Link` header.
@@ -283,7 +285,7 @@ for await (let commit of fetchCommits(repo)) {
283285
}
284286
```
285287
286-
We'd like to make a function `fetchCommits(repo)` that gets commits for us, making requests whenever needed. And let it care about all pagination stuff, for us it'll be a simple `for await..of`.
288+
We'd like to make a function `fetchCommits(repo)` that gets commits for us, making requests whenever needed. And let it care about all pagination stuff. For us it'll be a simple `for await..of`.
287289
288290
With async generators that's pretty easy to implement:
289291

‎1-js/13-modules/01-modules-intro/article.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ The `import` directive loads the module by path `./sayHi.js` relative the curren
4949

5050
Let's run the example in-browser.
5151

52-
As modules support special keywords and features, we must tell the browser that a script should be treated as module, by using the attribute `<script type="module">`.
52+
As modules support special keywords and features, we must tell the browser that a script should be treated as a module, by using the attribute `<script type="module">`.
5353

5454
Like this:
5555

@@ -165,7 +165,7 @@ So, let's reiterate -- the module is executed only once. Exports are generated,
165165

166166
Such behavior allows to *configure* modules on first import. We can setup its properties once, and then in further imports it's ready.
167167

168-
For instance, `admin.js` module may provide certain functionality, but expect the credentials to come into the `admin` object from outside:
168+
For instance, the `admin.js` module may provide certain functionality, but expect the credentials to come into the `admin` object from outside:
169169

170170
```js
171171
// 📁 admin.js
@@ -236,7 +236,7 @@ You may want skip this section for now if you're reading for the first time, or
236236
Module scripts are *always* deferred, same effect as `defer` attribute (described in the chapter [](info:script-async-defer)), for both external and inline scripts.
237237
238238
In other words:
239-
- downloading of external module scripts `<script type="module" src="...">` doesn't block HTML processing, they load in parallel with other resources.
239+
- downloading external module scripts `<script type="module" src="...">` doesn't block HTML processing, they load in parallel with other resources.
240240
- module scripts wait until the HTML document is fully ready (even if they are tiny and load faster than HTML), and then run.
241241
- relative order of scripts is maintained: scripts that go first in the document, execute first.
242242
@@ -264,21 +264,21 @@ Compare to regular script below:
264264
<button id="button">Button</button>
265265
```
266266
267-
Please note: the second script actually works before the first! So we'll see `undefined` first, and then `object`.
267+
Please note: the second script actually runs before the first! So we'll see `undefined` first, and then `object`.
268268
269-
That's because modules are deferred, so we wait for the document to be processed. The regular scripts runs immediately, so we saw its output first.
269+
That's because modules are deferred, so we wait for the document to be processed. The regular script runs immediately, so we see its output first.
270270
271271
When using modules, we should be aware that HTML-page shows up as it loads, and JavaScript modules run after that, so the user may see the page before the JavaScript application is ready. Some functionality may not work yet. We should put "loading indicators", or otherwise ensure that the visitor won't be confused by that.
272272
273273
### Async works on inline scripts
274274
275275
For non-module scripts, `async` attribute only works on external scripts. Async scripts run immediately when ready, independently of other scripts or the HTML document.
276276
277-
For module scripts, it works on any scripts.
277+
For module scripts, it works on inline scripts as well.
278278
279-
For example, the script below has `async`, so it doesn't wait for anyone.
279+
For example, the inline script below has `async`, so it doesn't wait for anything.
280280
281-
It performs the import (fetches `./analytics.js`) and runs when ready, even if HTML document is not finished yet, or if other scripts are still pending.
281+
It performs the import (fetches `./analytics.js`) and runs when ready, even if the HTML document is not finished yet, or if other scripts are still pending.
282282
283283
That's good for functionality that doesn't depend on anything, like counters, ads, document-level event listeners.
284284
@@ -296,7 +296,7 @@ That's good for functionality that doesn't depend on anything, like counters, ad
296296
297297
External scripts that have `type="module"` are different in two aspects:
298298
299-
1. External scripts with same `src` run only once:
299+
1. External scripts with the same `src` run only once:
300300
```html
301301
<!-- the script my.js is fetched and executed only once -->
302302
<script type="module" src="my.js"></script>
@@ -322,11 +322,11 @@ import {sayHi} from 'sayHi'; // Error, "bare" module
322322
// the module must have a path, e.g. './sayHi.js' or wherever the module is
323323
```
324324
325-
Certain environments, like Node.js or bundle tools allow bare modules, without any path, as they have own ways for finding modules and hooks to fine-tune them. But browsers do not support bare modules yet.
325+
Certain environments, like Node.js or bundle tools allow bare modules, without any path, as they have their own ways for finding modules and hooks to fine-tune them. But browsers do not support bare modules yet.
326326
327327
### Compatibility, "nomodule"
328328
329-
Old browsers do not understand `type="module"`. Scripts of the unknown type are just ignored. For them, it's possible to provide a fallback using `nomodule` attribute:
329+
Old browsers do not understand `type="module"`. Scripts of an unknown type are just ignored. For them, it's possible to provide a fallback using the `nomodule` attribute:
330330
331331
```html run
332332
<script type="module">
@@ -350,7 +350,7 @@ Build tools do the following:
350350
1. Take a "main" module, the one intended to be put in `<script type="module">` in HTML.
351351
2. Analyze its dependencies: imports and then imports of imports etc.
352352
3. Build a single file with all modules (or multiple files, that's tunable), replacing native `import` calls with bundler functions, so that it works. "Special" module types like HTML/CSS modules are also supported.
353-
4. In the process, other transforms and optimizations may be applied:
353+
4. In the process, other transformations and optimizations may be applied:
354354
- Unreachable code removed.
355355
- Unused exports removed ("tree-shaking").
356356
- Development-specific statements like `console` and `debugger` removed.
@@ -379,7 +379,7 @@ To summarize, the core concepts are:
379379
3. Modules always `use strict`.
380380
4. Module code is executed only once. Exports are created once and shared between importers.
381381
382-
When we use modules, each module implements the functionality and exports it. Then we use `import` to directly import it where it's needed. Browser loads and evaluates the scripts automatically.
382+
When we use modules, each module implements the functionality and exports it. Then we use `import` to directly import it where it's needed. The browser loads and evaluates the scripts automatically.
383383
384384
In production, people often use bundlers such as [Webpack](https://webpack.js.org) to bundle modules together for performance and other reasons.
385385

‎1-js/13-modules/02-import-export/article.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,14 @@ say.*!*bye*/!*('John'); // Bye, John!
155155

156156
In practice, there are mainly two kinds of modules.
157157

158-
1. Module that contains a library, pack of functions, like `say.js` above.
159-
2. Module that declares a single entity, e.g. a module `user.js` exports only `class User`.
158+
1. Modules that contain a library, pack of functions, like `say.js` above.
159+
2. Modules that declare a single entity, e.g. a module `user.js` exports only `class User`.
160160

161161
Mostly, the second approach is preferred, so that every "thing" resides in its own module.
162162

163-
Naturally, that requires a lot of files, as everything wants its own module, but that's not a problem at all. Actually, code navigation becomes easier, if files are well-named and structured into folders.
163+
Naturally, that requires a lot of files, as everything wants its own module, but that's not a problem at all. Actually, code navigation becomes easier if files are well-named and structured into folders.
164164
165-
Modules provide special `export default` ("the default export") syntax to make "one thing per module" way look better.
165+
Modules provide special `export default` ("the default export") syntax to make the "one thing per module" way look better.
166166
167167
Put `export default` before the entity to export:
168168
@@ -291,7 +291,7 @@ import {User} from './user.js';
291291
```js
292292
import User from './user.js'; // works
293293
import MyUser from './user.js'; // works too
294-
// could be import Anything..., and it'll be work
294+
// could be import Anything... and it'll still work
295295
```
296296

297297
So team members may use different names to import the same thing, and that's not good.
@@ -319,7 +319,7 @@ export {sayHi} from './say.js'; // re-export sayHi
319319
export {default as User} from './user.js'; // re-export default
320320
```
321321
322-
Why that may be needed? Let's see a practical use case.
322+
Why would that be needed? Let's see a practical use case.
323323

324324
Imagine, we're writing a "package": a folder with a lot of modules, with some of the functionality exported outside (tools like NPM allow to publish and distribute such packages), and many modules are just "helpers", for the internal use in other package modules.
325325
@@ -389,17 +389,17 @@ export default class User {
389389
390390
1. `export User from './user.js'` won't work. What can go wrong?... But that's a syntax error!
391391
392-
To re-export the default export, we should write `export {default as User}`, as in the example above.
392+
To re-export the default export, we have to write `export {default as User}`, as in the example above.
393393
394-
2. `export * from './user.js'` re-exports only named exports, ignores the default one.
394+
2. `export * from './user.js'` re-exports only named exports, but ignores the default one.
395395
396396
If we'd like to re-export both named and the default export, then two statements are needed:
397397
```js
398398
export * from './user.js'; // to re-export named exports
399399
export {default} from './user.js'; // to re-export the default export
400400
```
401401

402-
Such oddities of re-exporting the default export is one of the reasons, why some developers don't like them.
402+
Such oddities of re-exporting the default export are one of the reasons why some developers don't like them.
403403
404404
## Summary
405405

‎1-js/99-js-misc/01-proxy/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ Other traps exist: the full list is in the beginning of this chapter. Their usag
593593

594594
`Reflect` is a built-in object that simplifies creation of `Proxy`.
595595

596-
It was said previously that internal methods, such as `[[Get]]`, `[[Set]]` and others are specifiction only, they can't be called directly.
596+
It was said previously that internal methods, such as `[[Get]]`, `[[Set]]` and others are specification-only, they can't be called directly.
597597

598598
The `Reflect` object makes that somewhat possible. Its methods are minimal wrappers around the internal methods.
599599

‎2-ui/1-document/03-dom-navigation/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,12 @@ Till now we described the basic navigation properties.
280280
281281
Certain types of DOM elements may provide additional properties, specific to their type, for convenience.
282282
283-
Tables are a great example of that, and a particularly important case.
283+
Tables are a great example of that, and represent a particularly important case:
284284
285285
**The `<table>`** element supports (in addition to the given above) these properties:
286286
- `table.rows` -- the collection of `<tr>` elements of the table.
287287
- `table.caption/tHead/tFoot` -- references to elements `<caption>`, `<thead>`, `<tfoot>`.
288-
- `table.tBodies` -- the collection of `<tbody>` elements (can be many according to the standard).
288+
- `table.tBodies` -- the collection of `<tbody>` elements (can be many according to the standard, but there will always be at least one -- even if it is not in the source HTML, the browser will put it in the DOM).
289289
290290
**`<thead>`, `<tfoot>`, `<tbody>`** elements provide the `rows` property:
291291
- `tbody.rows` -- the collection of `<tr>` inside.

‎2-ui/1-document/07-modifying-document/12-sort-table/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ table.tBodies[0].append(...sortedRows);
1414
3. Then sort them comparing by the content of the first `<td>` (the name field).
1515
4. Now insert nodes in the right order by `.append(...sortedRows)`.
1616

17-
Tables always have an implicit <tbody> element, so we need to take it and insert into it: a simple `table.append(...)` would fail.
17+
Tables always have an implicit `<tbody>` element, so we need to take it and insert into it: a simple `table.append(...)` would fail.
1818

1919
Please note: we don't have to remove them, just "re-insert", they leave the old place automatically.

‎2-ui/1-document/07-modifying-document/5-why-aaa/task.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ importance: 1
44

55
# Why does "aaa" remain?
66

7-
Run the example. Why does `table.remove()` not delete the text `"aaa"`?
7+
In the example below, the call `table.remove()` removes the table from the document.
8+
9+
But if you run it, you can see that the text `"aaa"` is still visible.
10+
11+
Why does that happen?
812

913
```html height=100 run
1014
<table id="table">

‎2-ui/1-document/08-styles-and-classes/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ Visited links may be colored using `:visited` CSS pseudoclass.
282282

283283
But `getComputedStyle` does not give access to that color, because otherwise an arbitrary page could find out whether the user visited a link by creating it on the page and checking the styles.
284284

285-
JavaScript may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids to apply geometry-changing styles in `:visited`. That's to guarantee that there's no sideway for an evil page to test if a link was visited and hence to break the privacy.
285+
JavaScript may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids applying geometry-changing styles in `:visited`. That's to guarantee that there's no side way for an evil page to test if a link was visited and hence to break the privacy.
286286
```
287287
288288
## Summary

‎2-ui/1-document/09-size-and-scroll/1-get-scroll-height-bottom/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ importance: 5
44

55
# What's the scroll from the bottom?
66

7-
The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get the size from the bottom scroll (let's call it `scrollBottom`)?
7+
The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get the size of the bottom scroll (let's call it `scrollBottom`)?
88

99
Write the code that works for an arbitrary `elem`.
1010

‎2-ui/1-document/09-size-and-scroll/article.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ Let's start exploring the properties starting from the outside of the element.
5555
5656
These properties are rarely needed, but still they are the "most outer" geometry properties, so we'll start with them.
5757
58-
The `offsetParent` is the nearest ancestor, that browser uses for calculating coordinates during rendering.
58+
The `offsetParent` is the nearest ancestor that the browser uses for calculating coordinates during rendering.
5959
60-
That's the nearest ancestor, that satisfies following conditions:
60+
That's the nearest ancestor that is one of the following:
6161
62-
1. CSS-positioned (`position` is `absolute`, `relative`, `fixed` or `sticky`),
63-
2. or `<td>`, `<th>`, `<table>`,
64-
2. or `<body>`.
62+
1. CSS-positioned (`position` is `absolute`, `relative`, `fixed` or `sticky`), or
63+
2. `<td>`, `<th>`, or `<table>`, or
64+
3. `<body>`.
6565
6666
Properties `offsetLeft/offsetTop` provide x/y coordinates relative to `offsetParent` upper-left corner.
6767
@@ -104,7 +104,7 @@ For our sample element:
104104
````smart header="Geometry properties are zero/null for elements that are not displayed"
105105
Geometry properties are calculated only for displayed elements.
106106
107-
If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero (or `null` if that's `offsetParent`).
107+
If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero (or `null` for `offsetParent`).
108108
109109
For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or it's ancestor) has `display:none`.
110110
@@ -243,9 +243,9 @@ Why should we use geometry properties instead? There are two reasons:
243243
</script>
244244
```
245245
246-
From the CSS standpoint, `width:auto` is perfectly normal, but in JavaScript we need an exact size in `px` that we can use in calculations. So here CSS width is useless at all.
246+
From the CSS standpoint, `width:auto` is perfectly normal, but in JavaScript we need an exact size in `px` that we can use in calculations. So here CSS width is useless.
247247
248-
And there's one more reason: a scrollbar. Sometimes the code that works fine without a scrollbar starts to bug with it, because a scrollbar takes the space from the content in some browsers. So the real width available for the content is *less* than CSS width. And `clientWidth/clientHeight` take that into account.
248+
And there's one more reason: a scrollbar. Sometimes the code that works fine without a scrollbar becomes buggy with it, because a scrollbar takes the space from the content in some browsers. So the real width available for the content is *less* than CSS width. And `clientWidth/clientHeight` take that into account.
249249
250250
...But with `getComputedStyle(elem).width` the situation is different. Some browsers (e.g. Chrome) return the real inner width, minus the scrollbar, and some of them (e.g. Firefox) -- CSS width (ignore the scrollbar). Such cross-browser differences is the reason not to use `getComputedStyle`, but rather rely on geometry properties.
251251

‎2-ui/1-document/10-size-and-scroll-window/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Window sizes and scrolling
22

3-
How to find out the width and height of the browser window? How to get the full width and height of the document, including the scrolled out part? How to scroll the page using JavaScript?
3+
How do we find the width and height of the browser window? How do we get the full width and height of the document, including the scrolled out part? How do we scroll the page using JavaScript?
44

5-
For most such requests, we can use the root document element `document.documentElement`, that corresponds to `<html>` tag. But there are additional methods and peculiarities important enough to consider.
5+
For most such requests, we can use the root document element `document.documentElement`, that corresponds to the `<html>` tag. But there are additional methods and peculiarities important enough to consider.
66

77
## Width/height of the window
88

‎2-ui/1-document/11-coordinates/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,4 @@ Any point on the page has coordinates:
250250
251251
Window coordinates are great to use with `position:fixed`, and document coordinates do well with `position:absolute`.
252252
253-
Both coordinate systems have their "pro" and "contra", there are times we need one or the other one, just like CSS `position` `absolute` and `fixed`.
253+
Both coordinate systems have their pros and cons; there are times we need one or the other one, just like CSS `position` `absolute` and `fixed`.

‎2-ui/2-events/01-introduction-browser-events/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ In the code below `button` shows its contents using `this.innerHTML`:
148148

149149
## Possible mistakes
150150

151-
If you're starting to work with event -- please note some subtleties.
151+
If you're starting to work with events -- please note some subtleties.
152152

153153
**The function should be assigned as `sayThanks`, not `sayThanks()`.**
154154

@@ -181,7 +181,7 @@ button.onclick = function() {
181181

182182
**Use functions, not strings.**
183183

184-
The assignment `elem.onclick = "alert(1)"` would work too. It works for compatibility reasons, but strongly not recommended.
184+
The assignment `elem.onclick = "alert(1)"` would work too. It works for compatibility reasons, but is strongly not recommended.
185185

186186
**Don't use `setAttribute` for handlers.**
187187

‎2-ui/3-event-details/1-mouse-events-basics/article.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ The most used simple events are:
2121
`mousemove`
2222
: Every mouse move over an element triggers that event.
2323

24+
`contextmenu`
25+
: Triggers when opening a context menu is attempted. In the most common case, that happens when the right mouse button is pressed. Although, there are other ways to open a context menu, e.g. using a special keyboard key, so it's not exactly the mouse event.
26+
2427
...There are several other event types too, we'll cover them later.
2528

2629
### Complex events
2730

2831
`click`
2932
: Triggers after `mousedown` and then `mouseup` over the same element if the left mouse button was used.
3033

31-
`contextmenu`
32-
: Triggers after `mousedown` if the right mouse button was used.
33-
3434
`dblclick`
3535
: Triggers after a double click over an element.
3636

‎2-ui/3-event-details/4-mouse-drag-and-drop/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ In the modern HTML standard there's a [section about Drag and Drop](https://html
66

77
They are interesting because they allow to solve simple tasks easily, and also allow to handle drag'n'drop of "external" files into the browser. So we can take a file in the OS file-manager and drop it into the browser window. Then JavaScript gains access to its contents.
88

9-
But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be done using that API.
9+
But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be done using that API. Besides, mobile devices support for such events is almost non-existant.
1010

11-
Here we'll see how to implement Drag'n'Drop using mouse events.
11+
So here we'll see how to implement Drag'n'Drop using mouse events.
1212

1313
## Drag'n'Drop algorithm
1414

‎9-regular-expressions/01-regexp-introduction/article.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
# Patterns and flags
22

3-
Regular expressions is a powerful way to search and replace in text.
3+
Regular expressions are patterns that provide a powerful way to search and replace in text.
44

5-
In JavaScript, they are available as [RegExp](mdn:js/RegExp) object, and also integrated in methods of strings.
5+
In JavaScript, they are available via the [RegExp](mdn:js/RegExp) object, as well as being integrated in methods of strings.
66

77
## Regular Expressions
88

99
A regular expression (also "regexp", or just "reg") consists of a *pattern* and optional *flags*.
1010

11-
There are two syntaxes to create a regular expression object.
11+
There are two syntaxes that can be used to create a regular expression object.
1212

1313
The "long" syntax:
1414

1515
```js
1616
regexp = new RegExp("pattern", "flags");
1717
```
1818

19-
...And the short one, using slashes `"/"`:
19+
And the "short" one, using slashes `"/"`:
2020

2121
```js
2222
regexp = /pattern/; // no flags
@@ -25,11 +25,11 @@ regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)
2525

2626
Slashes `pattern:/.../` tell JavaScript that we are creating a regular expression. They play the same role as quotes for strings.
2727

28-
In both cases `regexp` becomes an object of the built-in `RegExp` class.
28+
In both cases `regexp` becomes an instance of the built-in `RegExp` class.
2929

30-
The main difference between these two syntaxes is that slashes `pattern:/.../` do not allow to insert expressions (like strings with `${...}`). They are fully static.
30+
The main difference between these two syntaxes is that pattern using slashes `/.../` does not allow for expressions to be inserted (like string template literals with `${...}`). They are fully static.
3131

32-
Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp` is used when we need to create a regexp "on the fly", from a dynamically generated string, for instance:
32+
Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp`, is more often used when we need to create a regexp "on the fly" from a dynamically generated string. For instance:
3333

3434
```js
3535
let tag = prompt("What tag do you want to find?", "h2");
@@ -47,7 +47,7 @@ There are only 6 of them in JavaScript:
4747
: With this flag the search is case-insensitive: no difference between `A` and `a` (see the example below).
4848

4949
`pattern:g`
50-
: With this flag the search looks for all matches, without it -- only the first one.
50+
: With this flag the search looks for all matches, without it -- only the first match is returned.
5151

5252
`pattern:m`
5353
: Multiline mode (covered in the chapter <info:regexp-multiline-mode>).
@@ -71,7 +71,7 @@ From here on the color scheme is:
7171

7272
## Searching: str.match
7373

74-
As it was said previously, regular expressions are integrated with string methods.
74+
As mentioned previously, regular expressions are integrated with string methods.
7575

7676
The method `str.match(regexp)` finds all matches of `regexp` in the string `str`.
7777

@@ -102,7 +102,7 @@ It has 3 working modes:
102102

103103
3. And, finally, if there are no matches, `null` is returned (doesn't matter if there's flag `pattern:g` or not).
104104

105-
That's a very important nuance. If there are no matches, we get not an empty array, but `null`. Forgetting about that may lead to errors, e.g.:
105+
This a very important nuance. If there are no matches, we don't receive an empty array, but instead receive `null`. Forgetting about that may lead to errors, e.g.:
106106
107107
```js run
108108
let matches = "JavaScript".match(/HTML/); // = null
@@ -112,7 +112,7 @@ It has 3 working modes:
112112
}
113113
```
114114
115-
If we'd like the result to be always an array, we can write it this way:
115+
If we'd like the result to always be an array, we can write it this way:
116116

117117
```js run
118118
let matches = "JavaScript".match(/HTML/)*!* || []*/!*;
@@ -124,7 +124,7 @@ It has 3 working modes:
124124

125125
## Replacing: str.replace
126126

127-
The method `str.replace(regexp, replacement)` replaces matches with `regexp` in string `str` with `replacement` (all matches, if there's flag `pattern:g`, otherwise only the first one).
127+
The method `str.replace(regexp, replacement)` replaces matches found using `regexp` in string `str` with `replacement` (all matches if there's flag `pattern:g`, otherwise, only the first one).
128128
129129
For instance:
130130
@@ -164,14 +164,14 @@ let regexp = /LOVE/i;
164164
alert( regexp.test(str) ); // true
165165
```
166166
167-
Further in this chapter we'll study more regular expressions, come across many other examples and also meet other methods.
167+
Later in this chapter we'll study more regular expressions, walk through more examples, and also meet other methods.
168168
169169
Full information about the methods is given in the article <info:regexp-methods>.
170170
171171
## Summary
172172
173173
- A regular expression consists of a pattern and optional flags: `pattern:g`, `pattern:i`, `pattern:m`, `pattern:u`, `pattern:s`, `pattern:y`.
174-
- Without flags and special symbols that we'll study later, the search by a regexp is the same as a substring search.
175-
- The method `str.match(regexp)` looks for matches: all of them if there's `pattern:g` flag, otherwise only the first one.
176-
- The method `str.replace(regexp, replacement)` replaces matches with `regexp` by `replacement`: all of them if there's `pattern:g` flag, otherwise only the first one.
177-
- The method `regexp.test(str)` returns `true` if there's at least one match, otherwise `false`.
174+
- Without flags and special symbols (that we'll study later), the search by a regexp is the same as a substring search.
175+
- The method `str.match(regexp)` looks for matches: all of them if there's `pattern:g` flag, otherwise, only the first one.
176+
- The method `str.replace(regexp, replacement)` replaces matches found using `regexp` with `replacement`: all of them if there's `pattern:g` flag, otherwise only the first one.
177+
- The method `regexp.test(str)` returns `true` if there's at least one match, otherwise, it returns `false`.

0 commit comments

Comments
 (0)
Please sign in to comment.