Skip to content

Commit 97b286b

Browse files
committedSep 28, 2020
Merge branch 'master' of github.com:javascript-tutorial/en.javascript.info into sync-f4891457
2 parents e1efdf7 + f489145 commit 97b286b

File tree

32 files changed

+350
-251
lines changed

32 files changed

+350
-251
lines changed
 

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Different engines have different "codenames". For example:
2626

2727
- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome and Opera.
2828
- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox.
29-
- ...There are other codenames like "Trident" and "Chakra" for different versions of IE, "ChakraCore" for Microsoft Edge, "Nitro" and "SquirrelFish" for Safari, etc.
29+
- ...There are other codenames like "Chakra" for IE, "ChakraCore" for Microsoft Edge, "Nitro" and "SquirrelFish" for Safari, etc.
3030

3131
The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome and Opera.
3232

‎1-js/02-first-steps/05-types/article.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,13 @@ const bigInt = 1234567890123456789012345678901234567890n;
8181

8282
As `BigInt` numbers are rarely needed, we don't cover them here, but devoted them a separate chapter <info:bigint>. Read it when you need such big numbers.
8383

84+
8485
```smart header="Compatibility issues"
85-
Right now `BigInt` is supported in Firefox/Chrome/Edge, but not in Safari/IE.
86+
Right now, `BigInt` is supported in Firefox/Chrome/Edge/Safari, but not in IE.
8687
```
8788

89+
You can check [*MDN* BigInt compatibility table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) to know which versions of a browser are supported.
90+
8891
## String
8992

9093
A string in JavaScript must be surrounded by quotes.

‎1-js/02-first-steps/08-operators/4-fix-prompt/solution.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ let b = "2"; // prompt("Second number?", 2);
99
alert(a + b); // 12
1010
```
1111

12-
What we should do is to convert strings to numbers before `+`. For example, using `Number()` or
13-
prepending them with `+`.
12+
What we should do is to convert strings to numbers before `+`. For example, using `Number()` or prepending them with `+`.
1413

1514
For example, right before `prompt`:
1615

‎1-js/02-first-steps/08-operators/article.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ Parentheses override any precedence, so if we're not satisfied with the default
180180
181181
There are many operators in JavaScript. Every operator has a corresponding precedence number. The one with the larger number executes first. If the precedence is the same, the execution order is from left to right.
182182
183-
Here's an extract from the [precedence table](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones):
183+
Here's an extract from the [precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones):
184184

185185
| Precedence | Name | Sign |
186186
|------------|------|------|

‎1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Some of the reasons:
1414

1515
1. Obviously, true.
1616
2. Dictionary comparison, hence false. `"a"` is smaller than `"p"`.
17-
3. Again, dictionary comparison, first char of `"2"` is greater than the first char of `"1"`.
17+
3. Again, dictionary comparison, first char `"2"` is greater than the first char `"1"`.
1818
4. Values `null` and `undefined` equal each other only.
1919
5. Strict equality is strict. Different types from both sides lead to false.
2020
6. Similar to `(4)`, `null` only equals `undefined`.

‎1-js/02-first-steps/09-comparison/article.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ In JavaScript they are written like this:
99
- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment.
1010
- Not equals. In maths the notation is <code>&ne;</code>, but in JavaScript it's written as <code>a != b</code>.
1111

12-
In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.
12+
In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.
1313

14-
At the end you'll find a good recipe to avoid "javascript quirks"-related issues.
14+
At the end you'll find a good recipe to avoid "JavaScript quirks"-related issues.
1515

1616
## Boolean is the result
1717

@@ -57,7 +57,7 @@ The algorithm to compare two strings is simple:
5757
4. Repeat until the end of either string.
5858
5. If both strings end at the same length, then they are equal. Otherwise, the longer string is greater.
5959

60-
In the examples above, the comparison `'Z' > 'A'` gets to a result at the first step while the strings `"Glow"` and `"Glee"` are compared character-by-character:
60+
In the examples above, the comparison `'Z' > 'A'` gets to a result at the first step while the strings `'Glow'` and `'Glee'` are compared character-by-character:
6161

6262
1. `G` is the same as `G`.
6363
2. `l` is the same as `l`.

‎1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md‎

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

55
# Check the range between
66

7-
Write an "if" condition to check that `age` is between `14` and `90` inclusively.
7+
Write an `if` condition to check that `age` is between `14` and `90` inclusively.
88

99
"Inclusively" means that `age` can reach the edges `14` or `90`.

‎1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md‎

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

55
# Check the range outside
66

7-
Write an `if` condition to check that `age` is NOT between 14 and 90 inclusively.
7+
Write an `if` condition to check that `age` is NOT between `14` and `90` inclusively.
88

99
Create two variants: the first one using NOT `!`, the second one -- without it.

‎1-js/02-first-steps/11-logical-operators/9-check-login/solution.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
```js run demo
44
let userName = prompt("Who's there?", '');
55

6-
if (userName == 'Admin') {
6+
if (userName === 'Admin') {
77

88
let pass = prompt('Password?', '');
99

10-
if (pass == 'TheMaster') {
10+
if (pass === 'TheMaster') {
1111
alert( 'Welcome!' );
12-
} else if (pass == '' || pass == null) {
12+
} else if (pass === '' || pass === null) {
1313
alert( 'Canceled' );
1414
} else {
1515
alert( 'Wrong password' );
1616
}
1717

18-
} else if (userName == '' || userName == null) {
18+
} else if (userName === '' || userName === null) {
1919
alert( 'Canceled' );
2020
} else {
2121
alert( "I don't know you" );

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ The OR `||` operator does the following:
8484

8585
A value is returned in its original form, without the conversion.
8686

87-
In other words, a chain of OR `"||"` returns the first truthy value or the last one if no truthy value is found.
87+
In other words, a chain of OR `||` returns the first truthy value or the last one if no truthy value is found.
8888

8989
For instance:
9090

@@ -101,9 +101,9 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl
101101

102102
1. **Getting the first truthy value from a list of variables or expressions.**
103103

104-
For instance, we have `firstName`, `lastName` and `nickName` variables, all optional.
104+
For instance, we have `firstName`, `lastName` and `nickName` variables, all optional (i.e. can be undefined or have falsy values).
105105

106-
Let's use OR `||` to choose the one that has the data and show it (or `anonymous` if nothing set):
106+
Let's use OR `||` to choose the one that has the data and show it (or `"Anonymous"` if nothing set):
107107

108108
```js run
109109
let firstName = "";
@@ -115,7 +115,7 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl
115115
*/!*
116116
```
117117

118-
If all variables were falsy, `Anonymous` would show up.
118+
If all variables were falsy, `"Anonymous"` would show up.
119119

120120
2. **Short-circuit evaluation.**
121121

@@ -223,7 +223,7 @@ The precedence of AND `&&` operator is higher than OR `||`.
223223
So the code `a && b || c && d` is essentially the same as if the `&&` expressions were in parentheses: `(a && b) || (c && d)`.
224224
````
225225
226-
````warn header="Don't replace `if` with || or &&"
226+
````warn header="Don't replace `if` with `||` or `&&`"
227227
Sometimes, people use the AND `&&` operator as a "shorter way to write `if`".
228228
229229
For instance:
@@ -244,7 +244,7 @@ let x = 1;
244244
if (x > 0) alert( 'Greater than zero!' );
245245
```
246246
247-
Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want if and use `&&` if we want AND.
247+
Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want `if` and use `&&` if we want AND.
248248
````
249249
250250

‎1-js/02-first-steps/12-nullish-coalescing-operator/article.md‎

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,92 @@
22

33
[recent browser="new"]
44

5-
The nullish coalescing operator `??` provides a short syntax for selecting a first "defined" variable from the list.
5+
Here, in this article, we'll say that an expression is "defined" when it's neither `null` nor `undefined`.
6+
7+
The nullish coalescing operator is written as two question marks `??`.
68

79
The result of `a ?? b` is:
8-
- `a` if it's not `null` or `undefined`,
9-
- `b`, otherwise.
10+
- if `a` is defined, then `a`,
11+
- if `a` isn't defined, then `b`.
12+
13+
14+
In other words, `??` returns the first argument if it's defined. Otherwise, the second one.
1015

11-
So, `x = a ?? b` is a short equivalent to:
16+
The nullish coalescing operator isn't anything completely new. It's just a nice syntax to get the first "defined" value of the two.
17+
18+
We can rewrite `result = a ?? b` using the operators that we already know, like this:
1219

1320
```js
14-
x = (a !== null && a !== undefined) ? a : b;
21+
result = (a !== null && a !== undefined) ? a : b;
22+
```
23+
24+
The common use case for `??` is to provide a default value for a potentially undefined variable.
25+
26+
For example, here we show `Anonymous` if `user` isn't defined:
27+
28+
```js run
29+
let user;
30+
31+
alert(user ?? "Anonymous"); // Anonymous
1532
```
1633
17-
Here's a longer example.
34+
Of course, if `user` had any value except `null/undefined`, then we would see it instead:
35+
36+
```js run
37+
let user = "John";
38+
39+
alert(user ?? "Anonymous"); // John
40+
```
1841
19-
Imagine, we have a user, and there are variables `firstName`, `lastName` or `nickName` for their first name, last name and the nick name. All of them may be undefined, if the user decided not to enter any value.
42+
We can also use a sequence of `??` to select the first defined value from a list.
2043
21-
We'd like to display the user name: one of these three variables, or show "Anonymous" if nothing is set.
44+
Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be undefined, if the user decided not to enter a value.
2245
23-
Let's use the `??` operator to select the first defined one:
46+
We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are undefined.
47+
48+
Let's use the `??` operator for that:
2449
2550
```js run
2651
let firstName = null;
2752
let lastName = null;
2853
let nickName = "Supercoder";
2954

30-
// show the first not-null/undefined value
55+
// shows the first defined value:
3156
*!*
3257
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
3358
*/!*
3459
```
3560
3661
## Comparison with ||
3762
38-
The OR `||` operator can be used in the same way as `??`. Actually, we can replace `??` with `||` in the code above and get the same result, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value).
39-
40-
The important difference is that:
41-
- `||` returns the first *truthy* value.
42-
- `??` returns the first *defined* value.
63+
The OR `||` operator can be used in the same way as `??`, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value).
4364
44-
This matters a lot when we'd like to treat `null/undefined` differently from `0`.
65+
For example, in the code above we could replace `??` with `||` and still get the same result:
4566
46-
For example, consider this:
67+
```js run
68+
let firstName = null;
69+
let lastName = null;
70+
let nickName = "Supercoder";
4771

48-
```js
49-
height = height ?? 100;
72+
// shows the first truthy value:
73+
*!*
74+
alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
75+
*/!*
5076
```
5177
52-
This sets `height` to `100` if it's not defined.
78+
The OR `||` operator exists since the beginning of JavaScript, so developers were using it for such purposes for a long time.
79+
80+
On the other hand, the nullish coalescing operator `??` was added only recently, and the reason for that was that people weren't quite happy with `||`.
5381
54-
Let's compare it with `||`:
82+
The subtle, yet important difference is that:
83+
- `||` returns the first *truthy* value.
84+
- `??` returns the first *defined* value.
85+
86+
In other words, `||` doesn't distinguish between `false`, `0`, an empty string `""` and `null/undefined`. They are all the same -- falsy values. If any of these is the first argument of `||`, then we'll get the second argument as the result.
87+
88+
In practice though, we may want to use default value only when the variable is `null/undefined`. That is, when the value is really unknown/not set.
89+
90+
For example, consider this:
5591
5692
```js run
5793
let height = 0;
@@ -60,19 +96,20 @@ alert(height || 100); // 100
6096
alert(height ?? 100); // 0
6197
```
6298
63-
Here, `height || 100` treats zero height as unset, same as `null`, `undefined` or any other falsy value. So the result is `100`.
99+
Here, we have a zero height.
64100
65-
The `height ?? 100` returns `100` only if `height` is exactly `null` or `undefined`. So the `alert` shows the height value `0` "as is".
101+
- The `height || 100` checks `height` for being a falsy value, and it really is.
102+
- so the result is the second argument, `100`.
103+
- The `height ?? 100` checks `height` for being `null/undefined`, and it's not,
104+
- so the result is `height` "as is", that is `0`.
66105
67-
Which behavior is better depends on a particular use case. When zero height is a valid value, then `??` is preferrable.
106+
If we assume that zero height is a valid value, that shouldn't be replaced with the default, then `??` does just the right thing.
68107
69108
## Precedence
70109
71-
The precedence of the `??` operator is rather low: `5` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
72-
73-
So `??` is evaluated after most other operations, but before `=` and `?`.
110+
The precedence of the `??` operator is rather low: `5` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). So `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`.
74111
75-
If we need to choose a value with `??` in a complex expression, then consider adding parentheses:
112+
So if we'd like to choose a value with `??` in an expression with other operators, consider adding parentheses:
76113
77114
```js run
78115
let height = null;
@@ -84,26 +121,27 @@ let area = (height ?? 100) * (width ?? 50);
84121
alert(area); // 5000
85122
```
86123
87-
Otherwise, if we omit parentheses, `*` has the higher precedence than `??` and would run first.
88-
89-
That would work be the same as:
124+
Otherwise, if we omit parentheses, then as `*` has the higher precedence than `??`, it would execute first, leading to incorrect results.
90125
91126
```js
92-
// probably not correct
127+
// without parentheses
128+
let area = height ?? 100 * width ?? 50;
129+
130+
// ...works the same as this (probably not what we want):
93131
let area = height ?? (100 * width) ?? 50;
94132
```
95133
96-
There's also a related language-level limitation.
134+
### Using ?? with && or ||
97135
98-
**Due to safety reasons, it's forbidden to use `??` together with `&&` and `||` operators.**
136+
Due to safety reasons, JavaScript forbids using `??` together with `&&` and `||` operators, unless the precedence is explicitly specified with parentheses.
99137
100138
The code below triggers a syntax error:
101139
102140
```js run
103141
let x = 1 && 2 ?? 3; // Syntax error
104142
```
105143
106-
The limitation is surely debatable, but it was added to the language specification with the purpose to avoid programming mistakes, as people start to switch to `??` from `||`.
144+
The limitation is surely debatable, but it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch to `??` from `||`.
107145
108146
Use explicit parentheses to work around it:
109147
@@ -126,5 +164,5 @@ alert(x); // 2
126164
height = height ?? 100;
127165
```
128166
129-
- The operator `??` has a very low precedence, a bit higher than `?` and `=`.
167+
- The operator `??` has a very low precedence, a bit higher than `?` and `=`, so consider adding parentheses when using it in an expression.
130168
- It's forbidden to use it with `||` or `&&` without explicit parentheses.

‎1-js/02-first-steps/15-function-basics/article.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ For instance, the aforementioned function `showMessage(from, text)` can be calle
185185
showMessage("Ann");
186186
```
187187
188-
That's not an error. Such a call would output `"Ann: undefined"`. There's no `text`, so it's assumed that `text === undefined`.
188+
That's not an error. Such a call would output `"*Ann*: undefined"`. There's no `text`, so it's assumed that `text === undefined`.
189189
190190
If we want to use a "default" `text` in this case, then we can specify it after `=`:
191191

0 commit comments

Comments
 (0)
Please sign in to comment.