Skip to content

Commit 863b07f

Browse files
committed
Merge branch 'master' of github.com:javascript-tutorial/en.javascript.info into sync-e1a3f634
2 parents 8b6d658 + e1a3f63 commit 863b07f

File tree

39 files changed

+188
-153
lines changed

39 files changed

+188
-153
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
@@ -110,7 +110,7 @@ Examples of such languages:
110110
- [TypeScript](http://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
111111
- [Flow](http://flow.org/) also adds data typing, but in a different way. Developed by Facebook.
112112
- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google.
113-
- [Brython](https://brython.info/) is a Python transpiler to JavaScript that allow to write application in pure Python without JavaScript.
113+
- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript.
114114

115115
There are more. Of course, even if we use one of transpiled languages, we should also know JavaScript to really understand what we're doing.
116116

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

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Object references and copying
22

3-
One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", as opposed to primitive values: strings, numbers, booleans, etc -- that are always copied "as a whole value".
3+
One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", whereas primitive values: strings, numbers, booleans, etc -- are always copied "as a whole value".
44

5-
That's easy to understand if we look a bit "under a cover" of what happens when we copy a value.
5+
That's easy to understand if we look a bit under the hood of what happens when we copy a value.
66

77
Let's start with a primitive, such as a string.
88

@@ -13,17 +13,17 @@ let message = "Hello!";
1313
let phrase = message;
1414
```
1515

16-
As a result we have two independent variables, each one is storing the string `"Hello!"`.
16+
As a result we have two independent variables, each one storing the string `"Hello!"`.
1717

1818
![](variable-copy-value.svg)
1919

2020
Quite an obvious result, right?
2121

2222
Objects are not like that.
2323

24-
**A variable assigned to an object stores not the object itself, but its "address in memory", in other words "a reference" to it.**
24+
**A variable assigned to an object stores not the object itself, but its "address in memory" -- in other words "a reference" to it.**
2525

26-
Let's look at an example of such variable:
26+
Let's look at an example of such a variable:
2727

2828
```js
2929
let user = {
@@ -37,13 +37,13 @@ And here's how it's actually stored in memory:
3737

3838
The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it.
3939

40-
We may think of an object variable, such as `user`, as of a sheet of paper with the address.
40+
We may think of an object variable, such as `user`, as like a sheet of paper with the address of the object on it.
4141

42-
When we perform actions with the object, e.g. take a property `user.name`, JavaScript engine looks into that address and performs the operation on the actual object.
42+
When we perform actions with the object, e.g. take a property `user.name`, the JavaScript engine looks at what's at that address and performs the operation on the actual object.
4343

4444
Now here's why it's important.
4545

46-
**When an object variable is copied -- the reference is copied, the object is not duplicated.**
46+
**When an object variable is copied, the reference is copied, but the object itself is not duplicated.**
4747

4848
For instance:
4949

@@ -53,13 +53,13 @@ let user = { name: "John" };
5353
let admin = user; // copy the reference
5454
```
5555

56-
Now we have two variables, each one with the reference to the same object:
56+
Now we have two variables, each storing a reference to the same object:
5757

5858
![](variable-copy-reference.svg)
5959

60-
As you can see, there's still one object, now with two variables that reference it.
60+
As you can see, there's still one object, but now with two variables that reference it.
6161

62-
We can use any variable to access the object and modify its contents:
62+
We can use either variable to access the object and modify its contents:
6363

6464
```js run
6565
let user = { name: 'John' };
@@ -73,7 +73,7 @@ admin.name = 'Pete'; // changed by the "admin" reference
7373
alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference
7474
```
7575
76-
It's just as if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes.
76+
It's as if we had a cabinet with two keys and used one of them (`admin`) to get into it and make changes. Then, if we later use another key (`user`), we are still opening the same cabinet and can access the changed contents.
7777
7878
## Comparison by reference
7979
@@ -98,15 +98,15 @@ let b = {}; // two independent objects
9898
alert( a == b ); // false
9999
```
100100
101-
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.
101+
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
103103
## Cloning and merging, Object.assign
104104
105105
So, copying an object variable creates one more reference to the same object.
106106
107107
But what if we need to duplicate an object? Create an independent copy, a clone?
108108
109-
That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time.
109+
That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. But there is rarely a need -- copying by reference is good most of the time.
110110
111111
But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level.
112112
@@ -225,12 +225,12 @@ user.sizes.width++; // change a property from one place
225225
alert(clone.sizes.width); // 51, see the result from the other one
226226
```
227227
228-
To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
228+
To fix that, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
229229
230-
We can use recursion to implement it. Or, not to reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
230+
We can use recursion to implement it. Or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
231231
232-
```smart header="Const objects can be modified"
233-
An important "side effect" of storing objects as references is that an object declared as `const` *can* be modified.
232+
````smart header="Const objects can be modified"
233+
An important side effect of storing objects as references is that an object declared as `const` *can* be modified.
234234

235235
For instance:
236236

@@ -246,16 +246,16 @@ user.name = "Pete"; // (*)
246246
alert(user.name); // Pete
247247
```
248248

249-
It might seem that the line `(*)` would cause an error, but no. The value of `user` is constant, it must always reference the same object. But properties of that object are free to change.
249+
It might seem that the line `(*)` would cause an error, but it does not. The value of `user` is constant, it must always reference the same object, but properties of that object are free to change.
250250

251-
In other words, the `const user` gives an error only if we try to set `user=...` as a whole, and that's all.
251+
In other words, the `const user` gives an error only if we try to set `user=...` as a whole.
252252

253-
That said, if we really need to make constant object properties, it's also possible, but using totally different methods, we'll mention that in the chapter <info:property-descriptors>.
254-
```
253+
That said, if we really need to make constant object properties, it's also possible, but using totally different methods. We'll mention that in the chapter <info:property-descriptors>.
254+
````
255255

256256
## Summary
257257

258-
Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object.
258+
Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself.
259259

260260
All operations via copied references (like adding/removing properties) are performed on the same single object.
261261

1-js/04-object-basics/07-optional-chaining/article.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ The optional chaining `?.` is a safe way to access nested object properties, eve
99

1010
If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common.
1111

12-
As an example, let's say we have `user` objects that hold the information about our users.
12+
As an example, let's say we have `user` objects that hold the information about our users.
1313

1414
Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them.
1515

@@ -21,7 +21,7 @@ let user = {}; // a user without "address" property
2121
alert(user.address.street); // Error!
2222
```
2323

24-
That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error.
24+
That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error.
2525

2626
In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").
2727

@@ -56,7 +56,7 @@ let user = {}; // user has no address
5656
alert(user.address ? user.address.street ? user.address.street.name : null : null);
5757
```
5858

59-
That's just awful, one may even have problems understanding such code.
59+
That's just awful, one may even have problems understanding such code.
6060

6161
Don't even care to, as there's a better way to write it, using the `&&` operator:
6262

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ alert( str.indexOf('widget') ); // -1, not found, the search is case-sensitive
239239
alert( str.indexOf("id") ); // 1, "id" is found at the position 1 (..idget with id)
240240
```
241241

242-
The optional second parameter allows us to search starting from the given position.
242+
The optional second parameter allows us to start searching from a given position.
243243

244244
For instance, the first occurrence of `"id"` is at position `1`. To look for the next occurrence, let's start the search from position `2`:
245245

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,8 @@ These methods are the most used ones, they cover 99% of use cases. But there are
742742
- [arr.some(fn)](mdn:js/Array/some)/[arr.every(fn)](mdn:js/Array/every) check the array.
743743

744744
The function `fn` is called on each element of the array similar to `map`. If any/all results are `true`, returns `true`, otherwise `false`.
745-
746-
These methods behave sort of like `||` and `&&` operators: if `fn` returns a truthy value, `arr.some()` immediately returns `true` and stops iterating over the rest items; if `fn` returns a falsy value, `arr.every()` immediately returns `false` and stops iterating over the rest items as well.
745+
746+
These methods behave sort of like `||` and `&&` operators: if `fn` returns a truthy value, `arr.some()` immediately returns `true` and stops iterating over the rest of items; if `fn` returns a falsy value, `arr.every()` immediately returns `false` and stops iterating over the rest of items as well.
747747

748748
We can use `every` to compare arrays:
749749
```js run

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

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

22
# Iterables
33

4-
*Iterable* objects is a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
4+
*Iterable* objects are a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
55

66
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable.
77

@@ -26,7 +26,7 @@ let range = {
2626
// for(let num of range) ... num=1,2,3,4,5
2727
```
2828

29-
To make the `range` iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that).
29+
To make the `range` object iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that).
3030

3131
1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
3232
2. Onward, `for..of` works *only with that returned object*.
@@ -140,7 +140,7 @@ for (let char of str) {
140140

141141
## Calling an iterator explicitly
142142

143-
For deeper understanding let's see how to use an iterator explicitly.
143+
For deeper understanding, let's see how to use an iterator explicitly.
144144

145145
We'll iterate over a string in exactly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually":
146146

@@ -165,16 +165,16 @@ That is rarely needed, but gives us more control over the process than `for..of`
165165

166166
## Iterables and array-likes [#array-like]
167167

168-
There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion.
168+
Two official terms look similar, but are very different. Please make sure you understand them well to avoid the confusion.
169169

170170
- *Iterables* are objects that implement the `Symbol.iterator` method, as described above.
171171
- *Array-likes* are objects that have indexes and `length`, so they look like arrays.
172172

173-
When we use JavaScript for practical tasks in browser or other environments, we may meet objects that are iterables or array-likes, or both.
173+
When we use JavaScript for practical tasks in a browser or any other environment, we may meet objects that are iterables or array-likes, or both.
174174

175175
For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`).
176176

177-
But an iterable may be not array-like. And vice versa an array-like may be not iterable.
177+
But an iterable may not be array-like. And vice versa an array-like may not be iterable.
178178

179179
For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`.
180180

@@ -293,7 +293,7 @@ alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs)
293293
Objects that can be used in `for..of` are called *iterable*.
294294

295295
- Technically, iterables must implement the method named `Symbol.iterator`.
296-
- The result of `obj[Symbol.iterator]()` is called an *iterator*. It handles the further iteration process.
296+
- The result of `obj[Symbol.iterator]()` is called an *iterator*. It handles further iteration process.
297297
- An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value.
298298
- The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly.
299299
- Built-in iterables like strings or arrays, also implement `Symbol.iterator`.

1-js/05-data-types/07-map-set/03-iterable-keys/task.md

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

55
# Iterable keys
66

7-
We'd like to get an array of `map.keys()` in a variable and then do apply array-specific methods to it, e.g. `.push`.
7+
We'd like to get an array of `map.keys()` in a variable and then apply array-specific methods to it, e.g. `.push`.
88

99
But that doesn't work:
1010

1-js/05-data-types/07-map-set/article.md

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

22
# Map and Set
33

4-
Now we've learned about the following complex data structures:
4+
Till now, we've learned about the following complex data structures:
55

6-
- Objects for storing keyed collections.
7-
- Arrays for storing ordered collections.
6+
- Objects are used for storing keyed collections.
7+
- Arrays are used for storing ordered collections.
88

99
But that's not enough for real life. That's why `Map` and `Set` also exist.
1010

@@ -42,7 +42,7 @@ alert( map.size ); // 3
4242
As we can see, unlike objects, keys are not converted to strings. Any type of key is possible.
4343

4444
```smart header="`map[key]` isn't the right way to use a `Map`"
45-
Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (no object keys and so on).
45+
Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (only string/symbol keys and so on).
4646

4747
So we should use `map` methods: `set`, `get` and so on.
4848
```
@@ -63,24 +63,26 @@ visitsCountMap.set(john, 123);
6363
alert( visitsCountMap.get(john) ); // 123
6464
```
6565

66-
Using objects as keys is one of most notable and important `Map` features. For string keys, `Object` can be fine, but not for object keys.
66+
Using objects as keys is one of the most notable and important `Map` features. The same does not count for `Object`. String as a key in `Object` is fine, but we can't use another `Object` as a key in `Object`.
6767

6868
Let's try:
6969

7070
```js run
7171
let john = { name: "John" };
72+
let ben = { name: "Ben" };
7273

7374
let visitsCountObj = {}; // try to use an object
7475

75-
visitsCountObj[john] = 123; // try to use john object as the key
76+
visitsCountObj[ben] = 234; // try to use ben object as the key
77+
visitsCountObj[john] = 123; // try to use john object as the key, ben object will get replaced
7678

7779
*!*
7880
// That's what got written!
79-
alert( visitsCountObj["[object Object]"] ); // 123
81+
alert( visitsCountObj["[object Object]"] ); // 123
8082
*/!*
8183
```
8284

83-
As `visitsCountObj` is an object, it converts all keys, such as `john` to strings, so we've got the string key `"[object Object]"`. Definitely not what we want.
85+
As `visitsCountObj` is an object, it converts all `Object` keys, such as `john` and `ben` above, to same string `"[object Object]"`. Definitely not what we want.
8486

8587
```smart header="How `Map` compares keys"
8688
To test keys for equivalence, `Map` uses the algorithm [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). It is roughly the same as strict equality `===`, but the difference is that `NaN` is considered equal to `NaN`. So `NaN` can be used as the key as well.
@@ -304,10 +306,10 @@ The same methods `Map` has for iterators are also supported:
304306
Methods and properties:
305307
306308
- `new Map([iterable])` -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
307-
- `map.set(key, value)` -- stores the value by the key.
309+
- `map.set(key, value)` -- stores the value by the key, returns the map itself.
308310
- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map.
309311
- `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise.
310-
- `map.delete(key)` -- removes the value by the key.
312+
- `map.delete(key)` -- removes the value by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`.
311313
- `map.clear()` -- removes everything from the map.
312314
- `map.size` -- returns the current element count.
313315

0 commit comments

Comments
 (0)