Skip to content

Commit e9200d1

Browse files
committed
Merge branch 'master' of github.com:javascript-tutorial/en.javascript.info into sync-fb4fc33a
2 parents 7fdcb48 + fb4fc33 commit e9200d1

File tree

16 files changed

+89
-68
lines changed

16 files changed

+89
-68
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 "Chakra" for IE, "ChakraCore" for Microsoft Edge, "Nitro" and "SquirrelFish" for Safari, etc.
29+
- ...There are other codenames like "Chakra" for IE, "JavaScriptCore", "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/02-structure/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ alert(3 +
4646
+ 2);
4747
```
4848

49-
The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so the semicolon is not required. And in this case that works as intended.
49+
The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so a semicolon there would be incorrect. And in this case, that works as intended.
5050

5151
**But there are situations where JavaScript "fails" to assume a semicolon where it is really needed.**
5252

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Special numeric values formally belong to the "number" type. Of course they are
6464

6565
We'll see more about working with numbers in the chapter <info:number>.
6666

67-
## BigInt
67+
## BigInt [#bigint-type]
6868

6969
In JavaScript, the "number" type cannot represent integer values larger than <code>(2<sup>53</sup>-1)</code> (that's `9007199254740991`), or less than <code>-(2<sup>53</sup>-1)</code> for negatives. It's a technical limitation caused by their internal representation.
7070

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ In school maths, we write that as a<sup>b</sup>.
6363
For instance:
6464

6565
```js run
66-
alert( 2 ** 2 ); // 2² = 4
67-
alert( 2 ** 3 ); // 2³ = 8
66+
alert( 2 ** 2 ); // 2² = 4
67+
alert( 2 ** 3 ); // 2³ = 8
6868
alert( 2 ** 4 ); // 2⁴ = 16
6969
```
7070

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

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ function showMessage() {
2020
}
2121
```
2222

23-
The `function` keyword goes first, then goes the *name of the function*, then a list of *parameters* between the parentheses (comma-separated, empty in the example above) and finally the code of the function, also named "the function body", between curly braces.
23+
The `function` keyword goes first, then goes the *name of the function*, then a list of *parameters* between the parentheses (comma-separated, empty in the example above, we'll see examples later) and finally the code of the function, also named "the function body", between curly braces.
2424

2525
```js
26-
function name(parameters) {
26+
function name(parameter1, parameter2, ... parameterN) {
2727
...body...
2828
}
2929
```
@@ -137,26 +137,23 @@ It's a good practice to minimize the use of global variables. Modern code has fe
137137

138138
## Parameters
139139

140-
We can pass arbitrary data to functions using parameters (also called *function arguments*) .
140+
We can pass arbitrary data to functions using parameters.
141141

142142
In the example below, the function has two parameters: `from` and `text`.
143143

144144
```js run
145-
function showMessage(*!*from, text*/!*) { // arguments: from, text
145+
function showMessage(*!*from, text*/!*) { // parameters: from, text
146146
alert(from + ': ' + text);
147147
}
148148

149-
*!*
150-
showMessage('Ann', 'Hello!'); // Ann: Hello! (*)
151-
showMessage('Ann', "What's up?"); // Ann: What's up? (**)
152-
*/!*
149+
*!*showMessage('Ann', 'Hello!');*/!* // Ann: Hello! (*)
150+
*!*showMessage('Ann', "What's up?");*/!* // Ann: What's up? (**)
153151
```
154152
155153
When the function is called in lines `(*)` and `(**)`, the given values are copied to local variables `from` and `text`. Then the function uses them.
156154
157155
Here's one more example: we have a variable `from` and pass it to the function. Please note: the function changes `from`, but the change is not seen outside, because a function always gets a copy of the value:
158156

159-
160157
```js run
161158
function showMessage(from, text) {
162159

@@ -175,19 +172,31 @@ showMessage(from, "Hello"); // *Ann*: Hello
175172
alert( from ); // Ann
176173
```
177174
175+
When a value is passed as a function parameter, it's also called an *argument*.
176+
177+
In other words, to put these terms straight:
178+
179+
- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term)
180+
- An argument is the value that is passed to the function when it is called (it's a call time term).
181+
182+
We declare functions listing their parameters, then call them passing arguments.
183+
184+
In the example above, one might say: "the function `sayMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
185+
186+
178187
## Default values
179188
180-
If a parameter is not provided, then its value becomes `undefined`.
189+
If a function is called, but an argument is not provided, then the corresponding value becomes `undefined`.
181190
182191
For instance, the aforementioned function `showMessage(from, text)` can be called with a single argument:
183192
184193
```js
185194
showMessage("Ann");
186195
```
187196
188-
That's not an error. Such a call would output `"*Ann*: undefined"`. There's no `text`, so it's assumed that `text === undefined`.
197+
That's not an error. Such a call would output `"*Ann*: undefined"`. As the value for `text` isn't passed, it becomes `undefined`.
189198
190-
If we want to use a "default" `text` in this case, then we can specify it after `=`:
199+
We can specify the so-called "default" (to use if omitted) value for a parameter in the function declaration, using `=`:
191200
192201
```js run
193202
function showMessage(from, *!*text = "no text given"*/!*) {
@@ -211,19 +220,23 @@ function showMessage(from, text = anotherFunction()) {
211220
```smart header="Evaluation of default parameters"
212221
In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter.
213222

214-
In the example above, `anotherFunction()` is called every time `showMessage()` is called without the `text` parameter.
223+
In the example above, `anotherFunction()` isn't called at all, if the `text` parameter is provided.
224+
225+
On the other hand, it's independently called every time when `text` is missing.
215226
```
216227

217228
### Alternative default parameters
218229

219-
Sometimes it makes sense to set default values for parameters not in the function declaration, but at a later stage, during its execution.
230+
Sometimes it makes sense to assign default values for parameters not in the function declaration, but at a later stage.
220231

221-
To check for an omitted parameter, we can compare it with `undefined`:
232+
We can check if the parameter is passed during the function execution, by comparing it with `undefined`:
222233

223234
```js run
224235
function showMessage(text) {
236+
// ...
237+
225238
*!*
226-
if (text === undefined) {
239+
if (text === undefined) { // if the parameter is missing
227240
text = 'empty message';
228241
}
229242
*/!*
@@ -234,21 +247,21 @@ function showMessage(text) {
234247
showMessage(); // empty message
235248
```
236249
237-
...Or we could use the `||` operator:
250+
...Or we could use the `??` operator:
238251
239252
```js
240-
// if text parameter is omitted or "" is passed, set it to 'empty'
241253
function showMessage(text) {
254+
// if text is undefined or otherwise falsy, set it to 'empty'
242255
text = text || 'empty';
243256
...
244257
}
245258
```
246259
247-
Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when falsy values, such as `0`, are considered regular:
260+
Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when most falsy values, such as `0`, should be considered "normal":
248261
249262
```js run
250-
// if there's no "count" parameter, show "unknown"
251263
function showCount(count) {
264+
// if count is undefined or null, show "unknown"
252265
alert(count ?? "unknown");
253266
}
254267

1-js/03-code-quality/01-debugging-chrome/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Debugging in Chrome
1+
# Debugging in the browser
22

33
Before writing more complex code, let's talk about debugging.
44

1-js/04-object-basics/06-constructor-new/article.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,14 @@ Now if we want to create other users, we can call `new User("Ann")`, `new User("
6464

6565
That's the main purpose of constructors -- to implement reusable object creation code.
6666

67-
Let's note once again -- technically, any function can be used as a constructor. That is: any function can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`.
67+
Let's note once again -- technically, any function (except arrow functions, as they don't have `this`) can be used as a constructor. It can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`.
6868

6969
````smart header="new function() { ... }"
70-
If we have many lines of code all about creation of a single complex object, we can wrap them in constructor function, like this:
70+
If we have many lines of code all about creation of a single complex object, we can wrap them in an immediately called constructor function, like this:
7171
7272
```js
73-
let user = new function() {
73+
// create a function and immediately call it with new
74+
let user = new function() {
7475
this.name = "John";
7576
this.isAdmin = false;
7677
@@ -80,7 +81,7 @@ let user = new function() {
8081
};
8182
```
8283
83-
The constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
84+
This constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
8485
````
8586

8687
## Constructor mode test: new.target

1-js/04-object-basics/09-object-toprimitive/article.md

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,36 @@
33

44
What happens when objects are added `obj1 + obj2`, subtracted `obj1 - obj2` or printed using `alert(obj)`?
55

6-
In that case, objects are auto-converted to primitives, and then the operation is carried out.
6+
JavaScript doesn't exactly allow to customize how operators work on objects. Unlike some other programming languages, such as Ruby or C++, we can't implement a special object method to handle an addition (or other operators).
7+
8+
In case of such operations, objects are auto-converted to primitives, and then the operation is carried out over these primitives and results in a primitive value.
9+
10+
That's an important limitation, as the result of `obj1 + obj2` can't be another object!
11+
12+
E.g. we can't make objects representing vectors or matrices (or archievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board".
13+
14+
So, because we can't do much here, there's no maths with objects in real projects. When it happens, it's usually because of a coding mistake.
15+
16+
In this chapter we'll cover how an object converts to primitive and how to customize it.
17+
18+
We have two purposes:
19+
20+
1. It will allow us to understand what's going on in case of coding mistakes, when such an operation happened accidentally.
21+
2. There are exceptions, where such operations are possible and look good. E.g. subtracting or comparing dates (`Date` objects). We'll come across them later.
22+
23+
## Conversion rules
724

825
In the chapter <info:type-conversions> we've seen the rules for numeric, string and boolean conversions of primitives. But we left a gap for objects. Now, as we know about methods and symbols it becomes possible to fill it.
926

1027
1. All objects are `true` in a boolean context. There are only numeric and string conversions.
1128
2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter <info:date>) can be subtracted, and the result of `date1 - date2` is the time difference between two dates.
1229
3. As for the string conversion -- it usually happens when we output an object like `alert(obj)` and in similar contexts.
1330

14-
## ToPrimitive
15-
1631
We can fine-tune string and numeric conversion, using special object methods.
1732

18-
There are three variants of type conversion, so-called "hints", described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive):
33+
There are three variants of type conversion, that happen in various situations.
34+
35+
They're called "hints", as described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive):
1936

2037
`"string"`
2138
: For an object-to-string conversion, when we're doing an operation on an object that expects a string, like `alert`:
@@ -82,11 +99,14 @@ Let's start from the first method. There's a built-in symbol named `Symbol.toPri
8299
83100
```js
84101
obj[Symbol.toPrimitive] = function(hint) {
85-
// must return a primitive value
102+
// here goes the code to convert this object to a primitive
103+
// it must return a primitive value
86104
// hint = one of "string", "number", "default"
87105
};
88106
```
89107

108+
If the method `Symbol.toPrimitive` exists, it's used for all hints, and no more methods are needed.
109+
90110
For instance, here `user` object implements it:
91111

92112
```js run
@@ -111,12 +131,12 @@ As we can see from the code, `user` becomes a self-descriptive string or a money
111131

112132
## toString/valueOf
113133

114-
Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
134+
If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`:
115135

116-
If there's no `Symbol.toPrimitive` then JavaScript tries to find them and try in the order:
136+
- For the "string" hint: `toString`, and if it doesn't exist, then `valueOf` (so `toString` has the priority for stirng conversions).
137+
- For other hints: `valueOf`, and if it doesn't exist, then `toString` (so `valueOf` has the priority for maths).
117138

118-
- `toString -> valueOf` for "string" hint.
119-
- `valueOf -> toString` otherwise.
139+
Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
120140

121141
These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method).
122142

@@ -136,9 +156,9 @@ alert(user.valueOf() === user); // true
136156

137157
So if we try to use an object as a string, like in an `alert` or so, then by default we see `[object Object]`.
138158

139-
And the default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist.
159+
The default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist.
140160

141-
Let's implement these methods.
161+
Let's implement these methods to customize the conversion.
142162

143163
For instance, here `user` does the same as above using a combination of `toString` and `valueOf` instead of `Symbol.toPrimitive`:
144164

@@ -183,7 +203,7 @@ alert(user + 500); // toString -> John500
183203

184204
In the absence of `Symbol.toPrimitive` and `valueOf`, `toString` will handle all primitive conversions.
185205

186-
## Return types
206+
### A conversion can return any primitive type
187207

188208
The important thing to know about all primitive-conversion methods is that they do not necessarily return the "hinted" primitive.
189209

@@ -252,4 +272,6 @@ The conversion algorithm is:
252272
3. Otherwise if hint is `"number"` or `"default"`
253273
- try `obj.valueOf()` and `obj.toString()`, whatever exists.
254274

255-
In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for all conversions that return a "human-readable" representation of an object, for logging or debugging purposes.
275+
In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes.
276+
277+
As for math operations, JavaScript doesn't provide a way to "override" them using methods, so real life projects rarely use them on objects.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ Now it becomes obvious why `a > Z`.
526526
The characters are compared by their numeric code. The greater code means that the character is greater. The code for `a` (97) is greater than the code for `Z` (90).
527527

528528
- All lowercase letters go after uppercase letters because their codes are greater.
529-
- Some letters like `Ö` stand apart from the main alphabet. Here, it's code is greater than anything from `a` to `z`.
529+
- Some letters like `Ö` stand apart from the main alphabet. Here, its code is greater than anything from `a` to `z`.
530530

531531
### Correct comparisons [#correct-comparisons]
532532

1-js/09-classes/04-private-protected-properties-methods/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ There's a finished JavaScript proposal, almost in the standard, that provides la
192192

193193
Privates should start with `#`. They are only accessible from inside the class.
194194

195-
For instance, here's a private `#waterLimit` property and the water-checking private method `#checkWater`:
195+
For instance, here's a private `#waterLimit` property and the water-checking private method `#fixWaterAmount`:
196196

197197
```js run
198198
class CoffeeMachine {

0 commit comments

Comments
 (0)