Skip to content

Commit 2caff35

Browse files
authored
Merge pull request #214 from javascript-tutorial/sync-e01998ba
Sync with upstream @ e01998b
2 parents 76b6892 + fea2f34 commit 2caff35

File tree

18 files changed

+191
-189
lines changed

18 files changed

+191
-189
lines changed

1-js/02-first-steps/11-logical-operators/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ if (hour < 10 || hour > 18 || isWeekend) {
6464
}
6565
```
6666

67-
## OR "||" finds the first truthy value
67+
## OR "||" finds the first truthy value [#or-finds-the-first-truthy-value]
6868

6969
The logic described above is somewhat classical. Now, let's bring in the "extra" features of JavaScript.
7070

1-js/02-first-steps/13-while-for/article.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ alert('Done!');
318318

319319
We need a way to stop the process if the user cancels the input.
320320

321-
The ordinary `break` after `input` would only break the inner loop. That's not sufficient--labels, come to the rescue!
321+
The ordinary `break` after `input` would only break the inner loop. That's not sufficient -- labels, come to the rescue!
322322

323323
A *label* is an identifier with a colon before a loop:
324324
```js
@@ -363,12 +363,14 @@ Labels do not allow us to jump into an arbitrary place in the code.
363363
364364
For example, it is impossible to do this:
365365
```js
366-
break label; // doesn't jumps to the label below
366+
break label; // jump to the label below (doesn't work)
367367
368368
label: for (...)
369369
```
370370
371-
A call to `break/continue` is only possible from inside a loop and the label must be somewhere above the directive.
371+
A call to `continue` is only possible from inside the loop.
372+
373+
The `break` directive may be placed before code blocks too, as `label: { ... }`, but it's almost never used like that. And it also works only inside-out.
372374
````
373375

374376
## Summary

1-js/04-object-basics/02-object-copy/article.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ alert( a == b ); // false
100100
101101
For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely -- usually they appear as a result of a programming mistake.
102102
103-
## Cloning and merging, Object.assign
103+
## Cloning and merging, Object.assign [#cloning-and-merging-object-assign]
104104
105105
So, copying an object variable creates one more reference to the same object.
106106
@@ -186,7 +186,7 @@ let clone = Object.assign({}, user);
186186
187187
It copies all properties of `user` into the empty object and returns it.
188188
189-
There are also other methods of cloning an object, e.g. using the [spread operator](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial.
189+
There are also other methods of cloning an object, e.g. using the [spread syntax](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial.
190190
191191
## Nested cloning
192192

1-js/05-data-types/02-number/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ There are two ways to do so:
160160
```js run
161161
let num = 1.23456;
162162

163-
alert( Math.floor(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
163+
alert( Math.round(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
164164
```
165165

166166
2. The method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) rounds the number to `n` digits after the point and returns a string representation of the result.

1-js/05-data-types/03-string/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ The characters are compared by their numeric code. The greater code means that t
528528
- All lowercase letters go after uppercase letters because their codes are greater.
529529
- Some letters like `Ö` stand apart from the main alphabet. Here, it's code is greater than anything from `a` to `z`.
530530

531-
### Correct comparisons
531+
### Correct comparisons [#correct-comparisons]
532532

533533
The "right" algorithm to do string comparisons is more complex than it may seem, because alphabets are different for different languages.
534534

1-js/06-advanced-functions/06-function-object/article.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
# Function object, NFE
33

4-
As we already know, functions in JavaScript are values.
4+
As we already know, a function in JavaScript is a value.
55

66
Every value in JavaScript has a type. What type is a function?
77

@@ -12,7 +12,7 @@ A good way to imagine functions is as callable "action objects". We can not only
1212

1313
## The "name" property
1414

15-
Function objects contain a few useable properties.
15+
Function objects contain some useable properties.
1616

1717
For instance, a function's name is accessible as the "name" property:
1818

@@ -24,14 +24,14 @@ function sayHi() {
2424
alert(sayHi.name); // sayHi
2525
```
2626

27-
What's more funny, the name-assigning logic is smart. It also assigns the correct name to functions that are used in assignments:
27+
What's kind of funny, the name-assigning logic is smart. It also assigns the correct name to a function even if it's created without one, and then immediately assigned:
2828

2929
```js run
3030
let sayHi = function() {
3131
alert("Hi");
32-
}
32+
};
3333

34-
alert(sayHi.name); // sayHi (works!)
34+
alert(sayHi.name); // sayHi (there's a name!)
3535
```
3636

3737
It also works if the assignment is done via a default value:
@@ -93,7 +93,7 @@ alert(many.length); // 2
9393

9494
Here we can see that rest parameters are not counted.
9595

96-
The `length` property is sometimes used for introspection in functions that operate on other functions.
96+
The `length` property is sometimes used for [introspection](https://en.wikipedia.org/wiki/Type_introspection) in functions that operate on other functions.
9797

9898
For instance, in the code below the `ask` function accepts a `question` to ask and an arbitrary number of `handler` functions to call.
9999

@@ -102,9 +102,9 @@ Once a user provides their answer, the function calls the handlers. We can pass
102102
- A zero-argument function, which is only called when the user gives a positive answer.
103103
- A function with arguments, which is called in either case and returns an answer.
104104

105-
The idea is that we have a simple, no-arguments handler syntax for positive cases (most frequent variant), but are able to provide universal handlers as well.
105+
To call `handler` the right way, we examine the `handler.length` property.
106106

107-
To call `handlers` the right way, we examine the `length` property:
107+
The idea is that we have a simple, no-arguments handler syntax for positive cases (most frequent variant), but are able to support universal handlers as well:
108108

109109
```js run
110110
function ask(question, ...handlers) {
@@ -153,7 +153,7 @@ alert( `Called ${sayHi.counter} times` ); // Called 2 times
153153
```warn header="A property is not a variable"
154154
A property assigned to a function like `sayHi.counter = 0` does *not* define a local variable `counter` inside it. In other words, a property `counter` and a variable `let counter` are two unrelated things.
155155
156-
We can treat a function as an object, store properties in it, but that has no effect on its execution. Variables never use function properties and vice versa. These are just parallel worlds.
156+
We can treat a function as an object, store properties in it, but that has no effect on its execution. Variables are not function properties and vice versa. These are just parallel worlds.
157157
```
158158

159159
Function properties can replace closures sometimes. For instance, we can rewrite the counter function example from the chapter <info:closure> to use a function property:
@@ -241,7 +241,7 @@ let sayHi = function *!*func*/!*(who) {
241241
sayHi("John"); // Hello, John
242242
```
243243

244-
There are two special things about the name `func`:
244+
There are two special things about the name `func`, that are the reasons for it:
245245

246246
1. It allows the function to reference itself internally.
247247
2. It is not visible outside of the function.
@@ -282,7 +282,7 @@ let sayHi = function(who) {
282282
};
283283
```
284284

285-
The problem with that code is that the value of `sayHi` may change. The function may go to another variable, and the code will start to give errors:
285+
The problem with that code is that `sayHi` may change in the outer code. If the function gets assigned to another variable instead, the code will start to give errors:
286286

287287
```js run
288288
let sayHi = function(who) {
@@ -326,7 +326,7 @@ welcome(); // Hello, Guest (nested call works)
326326

327327
Now it works, because the name `"func"` is function-local. It is not taken from outside (and not visible there). The specification guarantees that it will always reference the current function.
328328

329-
The outer code still has it's variable `sayHi` or `welcome`. And `func` is an "internal function name", how the function can call itself internally.
329+
The outer code still has its variable `sayHi` or `welcome`. And `func` is an "internal function name", how the function can call itself internally.
330330

331331
```smart header="There's no such thing for Function Declaration"
332332
The "internal name" feature described here is only available for Function Expressions, not for Function Declarations. For Function Declarations, there is no syntax for adding an "internal" name.
@@ -340,7 +340,7 @@ Functions are objects.
340340

341341
Here we covered their properties:
342342

343-
- `name` -- the function name. Exists not only when given in the function definition, but also for assignments and object properties.
343+
- `name` -- the function name. Usually taken from the function definition, but if there's none, JavaScript tries to guess it from the context (e.g. an assignment).
344344
- `length` -- the number of arguments in the function definition. Rest parameters are not counted.
345345

346346
If the function is declared as a Function Expression (not in the main code flow), and it carries the name, then it is called a Named Function Expression. The name can be used inside to reference itself, for recursive calls or such.

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
# Static properties and methods
33

4-
We can also assign a method to the class function, not to its `"prototype"`. Such methods are called *static*.
4+
We can also assign a method to the class function itself, not to its `"prototype"`. Such methods are called *static*.
55

6-
An example:
6+
In a class, they are prepended by `static` keyword, like this:
77

88
```js run
99
class User {
@@ -17,7 +17,7 @@ class User {
1717
User.staticMethod(); // true
1818
```
1919

20-
That actually does the same as assigning it as a function property:
20+
That actually does the same as assigning it as a property directly:
2121

2222
```js run
2323
class User { }
@@ -29,11 +29,11 @@ User.staticMethod = function() {
2929
User.staticMethod(); // true
3030
```
3131

32-
The value of `this` inside `User.staticMethod()` is the class constructor `User` itself (the "object before dot" rule).
32+
The value of `this` in `User.staticMethod()` call is the class constructor `User` itself (the "object before dot" rule).
3333

3434
Usually, static methods are used to implement functions that belong to the class, but not to any particular object of it.
3535

36-
For instance, we have `Article` objects and need a function to compare them. The natural choice would be `Article.compare`, like this:
36+
For instance, we have `Article` objects and need a function to compare them. A natural solution would be to add `Article.compare` method, like this:
3737

3838
```js run
3939
class Article {
@@ -51,25 +51,25 @@ class Article {
5151

5252
// usage
5353
let articles = [
54-
new Article("Mind", new Date(2019, 1, 1)),
55-
new Article("Body", new Date(2019, 0, 1)),
54+
new Article("HTML", new Date(2019, 1, 1)),
55+
new Article("CSS", new Date(2019, 0, 1)),
5656
new Article("JavaScript", new Date(2019, 11, 1))
5757
];
5858

5959
*!*
6060
articles.sort(Article.compare);
6161
*/!*
6262

63-
alert( articles[0].title ); // Body
63+
alert( articles[0].title ); // CSS
6464
```
6565

66-
Here `Article.compare` stands "over" the articles, as a means to compare them. It's not a method of an article, but rather of the whole class.
66+
Here `Article.compare` stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class.
6767

6868
Another example would be a so-called "factory" method. Imagine, we need few ways to create an article:
6969

7070
1. Create by given parameters (`title`, `date` etc).
7171
2. Create an empty article with today's date.
72-
3. ...
72+
3. ...or else somehow.
7373

7474
The first way can be implemented by the constructor. And for the second one we can make a static method of the class.
7575

@@ -109,7 +109,7 @@ Article.remove({id: 12345});
109109

110110
[recent browser=Chrome]
111111

112-
Static properties are also possible, just like regular class properties:
112+
Static properties are also possible, they look like regular class properties, but prepended by `static`:
113113

114114
```js run
115115
class Article {
@@ -125,7 +125,7 @@ That is the same as a direct assignment to `Article`:
125125
Article.publisher = "Ilya Kantor";
126126
```
127127

128-
## Inheritance of static properties and methods
128+
## Inheritance of static properties and methods [#statics-and-inheritance]
129129

130130
Static properties and methods are inherited.
131131

@@ -176,20 +176,24 @@ alert(Rabbit.planet); // Earth
176176

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

179-
How does it work? Again, using prototypes. As you might have already guessed, extends also gives `Rabbit` the `[[Prototype]]` reference to `Animal`.
180-
179+
How does it work? Again, using prototypes. As you might have already guessed, `extends` gives `Rabbit` the `[[Prototype]]` reference to `Animal`.
181180

182181
![](animal-rabbit-static.svg)
183182

183+
So, `Rabbit extends Animal` creates two `[[Prototype]]` references:
184+
185+
1. `Rabbit` function prototypally inherits from `Animal` function.
186+
2. `Rabbit.prototype` prototypally inherits from `Animal.prototype`.
187+
184188
As a result, inheritance works both for regular and static methods.
185189

186-
Here, let's check that:
190+
Here, let's check that by code:
187191

188192
```js run
189193
class Animal {}
190194
class Rabbit extends Animal {}
191195

192-
// for static properties and methods
196+
// for statics
193197
alert(Rabbit.__proto__ === Animal); // true
194198

195199
// for regular methods
@@ -200,9 +204,9 @@ alert(Rabbit.prototype.__proto__ === Animal.prototype); // true
200204

201205
Static methods are used for the functionality that belongs to the class "as a whole". It doesn't relate to a concrete class instance.
202206

203-
## Summary
207+
For example, a method for comparison `Article.compare(article1, article2)` or a factory method `Article.createTodays()`.
204208

205-
Static methods are used for the functionality that doesn't relate to a concrete class instance, doesn't require an instance to exist, but rather belongs to the class as a whole, like `Article.compare` -- a generic method to compare two articles.
209+
They are labeled by the word `static` in class declaration.
206210

207211
Static properties are used when we'd like to store class-level data, also not bound to an instance.
208212

@@ -218,13 +222,13 @@ class MyClass {
218222
}
219223
```
220224

221-
That's technically the same as assigning to the class itself:
225+
Technically, static declaration is the same as assigning to the class itself:
222226

223227
```js
224228
MyClass.property = ...
225229
MyClass.method = ...
226230
```
227231

228-
Static properties are inherited.
232+
Static properties and methods are inherited.
229233

230-
Technically, for `class B extends A` the prototype of the class `B` itself points to `A`: `B.[[Prototype]] = A`. So if a field is not found in `B`, the search continues in `A`.
234+
For `class B extends A` the prototype of the class `B` itself points to `A`: `B.[[Prototype]] = A`. So if a field is not found in `B`, the search continues in `A`.

1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
The difference becomes obvious when we look at the code inside a function.
22

3-
The behavior is different if there's a "jump out" of `try..catch`.
3+
The behavior is different if there's a "jump out" of `try...catch`.
44

5-
For instance, when there's a `return` inside `try..catch`. The `finally` clause works in case of *any* exit from `try..catch`, even via the `return` statement: right after `try..catch` is done, but before the calling code gets the control.
5+
For instance, when there's a `return` inside `try...catch`. The `finally` clause works in case of *any* exit from `try...catch`, even via the `return` statement: right after `try...catch` is done, but before the calling code gets the control.
66

77
```js run
88
function f() {
@@ -11,7 +11,7 @@ function f() {
1111
*!*
1212
return "result";
1313
*/!*
14-
} catch (e) {
14+
} catch (err) {
1515
/// ...
1616
} finally {
1717
alert('cleanup!');
@@ -28,11 +28,11 @@ function f() {
2828
try {
2929
alert('start');
3030
throw new Error("an error");
31-
} catch (e) {
31+
} catch (err) {
3232
// ...
3333
if("can't handle the error") {
3434
*!*
35-
throw e;
35+
throw err;
3636
*/!*
3737
}
3838

@@ -44,4 +44,4 @@ function f() {
4444
f(); // cleanup!
4545
```
4646

47-
It's `finally` that guarantees the cleanup here. If we just put the code at the end of `f`, it wouldn't run.
47+
It's `finally` that guarantees the cleanup here. If we just put the code at the end of `f`, it wouldn't run in these situations.

1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ importance: 5
66

77
Compare the two code fragments.
88

9-
1. The first one uses `finally` to execute the code after `try..catch`:
9+
1. The first one uses `finally` to execute the code after `try...catch`:
1010

1111
```js
1212
try {
1313
work work
14-
} catch (e) {
14+
} catch (err) {
1515
handle errors
1616
} finally {
1717
*!*
1818
cleanup the working space
1919
*/!*
2020
}
2121
```
22-
2. The second fragment puts the cleaning right after `try..catch`:
22+
2. The second fragment puts the cleaning right after `try...catch`:
2323

2424
```js
2525
try {
2626
work work
27-
} catch (e) {
27+
} catch (err) {
2828
handle errors
2929
}
3030
@@ -33,6 +33,6 @@ Compare the two code fragments.
3333
*/!*
3434
```
3535

36-
We definitely need the cleanup after the work has started, doesn't matter if there was an error or not.
36+
We definitely need the cleanup after the work, doesn't matter if there was an error or not.
3737
3838
Is there an advantage here in using `finally` or both code fragments are equal? If there is such an advantage, then give an example when it matters.

0 commit comments

Comments
 (0)