You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/02-object-copy/article.md
+75-17Lines changed: 75 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -100,6 +100,30 @@ alert( a == b ); // false
100
100
101
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.
102
102
103
+
````smart header="Const objects can be modified"
104
+
An important side effect of storing objects as references is that an object declared as `const` *can* bemodified.
105
+
106
+
For instance:
107
+
108
+
```js run
109
+
const user = {
110
+
name: "John"
111
+
};
112
+
113
+
*!*
114
+
user.name = "Pete"; // (*)
115
+
*/!*
116
+
117
+
alert(user.name); // Pete
118
+
```
119
+
120
+
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.
121
+
122
+
In other words, the `const user` gives an error only if we try to set `user=...` as a whole.
123
+
124
+
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>.
125
+
````
126
+
103
127
## Cloning and merging, Object.assign [#cloning-and-merging-object-assign]
104
128
105
129
So, copying an object variable creates one more reference to the same object.
@@ -136,7 +160,7 @@ We can also use the method [Object.assign](https://developer.mozilla.org/en-US/d
136
160
The syntax is:
137
161
138
162
```js
139
-
Object.assign(dest, [src1, src2, src3...])
163
+
Object.assign(dest, src1[, src2, src3...])
140
164
```
141
165
142
166
- The first argument `dest` is a target object.
@@ -219,42 +243,76 @@ let clone = Object.assign({}, user);
219
243
alert( user.sizes === clone.sizes ); // true, same object
220
244
221
245
// user and clone share sizes
222
-
user.sizes.width++; // change a property from one place
223
-
alert(clone.sizes.width); //51, get the result from the other one
246
+
user.sizes.width = 60; // change a property from one place
247
+
alert(clone.sizes.width); // 60, get the result from the other one
224
248
```
225
249
226
-
To fix that and make `user` and `clone` truly separate objects, 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".
250
+
To fix that and make `user` and `clone` truly separate objects, 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" or "structured cloning". There's [structuredClone](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) method that implements deep cloning.
227
251
228
-
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).
229
252
230
-
````smart header="Const objects can be modified"
231
-
An important side effect of storing objects as references is that an object declared as `const` *can* bemodified.
253
+
### structuredClone
232
254
233
-
For instance:
255
+
The call `structuredClone(object)` clones the `object` with all nested properties.
256
+
257
+
Here's how we can use it in our example:
234
258
235
259
```js run
236
-
const user = {
237
-
name: "John"
260
+
let user = {
261
+
name: "John",
262
+
sizes: {
263
+
height: 182,
264
+
width: 50
265
+
}
238
266
};
239
267
240
268
*!*
241
-
user.name = "Pete"; // (*)
269
+
let clone = structuredClone(user);
242
270
*/!*
243
271
244
-
alert(user.name); // Pete
272
+
alert( user.sizes === clone.sizes ); // false, different objects
273
+
274
+
// user and clone are totally unrelated now
275
+
user.sizes.width = 60; // change a property from one place
276
+
alert(clone.sizes.width); // 50, not related
245
277
```
246
278
247
-
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.
279
+
The `structuredClone` method can clone most data types, such as objects, arrays, primitive values.
248
280
249
-
In other words, the `const user` gives an error only if we try to set `user=...` as a whole.
281
+
It also supports circular references, when an object property references the object itself (directly or via a chain or references).
250
282
251
-
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>.
252
-
````
283
+
For instance:
284
+
285
+
```js run
286
+
let user = {};
287
+
// let's create a circular reference:
288
+
// user.me references the user itself
289
+
user.me = user;
290
+
291
+
let clone = structuredClone(user);
292
+
alert(clone.me === clone); // true
293
+
```
294
+
295
+
As you can see, `clone.me` references the `clone`, not the `user`! So the circular reference was cloned correctly as well.
296
+
297
+
Although, there are cases when `structuredClone` fails.
298
+
299
+
For instance, when an object has a function property:
300
+
301
+
```js run
302
+
// error
303
+
structuredClone({
304
+
f:function() {}
305
+
});
306
+
```
307
+
308
+
Function properties aren't supported.
309
+
310
+
To handle such complex cases we may need to use a combination of cloning methods, write custom code 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).
253
311
254
312
## Summary
255
313
256
314
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.
257
315
258
316
All operations via copied references (like adding/removing properties) are performed on the same single object.
259
317
260
-
To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
318
+
To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function `structuredClone` or use a custom cloning implementation, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
Copy file name to clipboardExpand all lines: 1-js/09-classes/07-mixins/article.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -103,7 +103,7 @@ Here's the diagram (see the right part):
103
103
104
104
That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above.
105
105
106
-
As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`.
106
+
As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`.
Copy file name to clipboardExpand all lines: 1-js/11-async/03-promise-chaining/article.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -224,7 +224,7 @@ This feature allows us to integrate custom objects with promise chains without h
224
224
225
225
## Bigger example: fetch
226
226
227
-
In frontend programming promises are often used for network requests. So let's see an extended example of that.
227
+
In frontend programming, promises are often used for network requests. So let's see an extended example of that.
228
228
229
229
We'll use the [fetch](info:fetch) method to load the information about the user from the remote server. It has a lot of optional parameters covered in [separate chapters](info:fetch), but the basic syntax is quite simple:
Copy file name to clipboardExpand all lines: 1-js/13-modules/01-modules-intro/article.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ To name some (for historical reasons):
13
13
-[CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.js server.
14
14
-[UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS.
15
15
16
-
Now all these slowly become a part of history, but we still can find them in old scripts.
16
+
Now these all slowly became a part of history, but we still can find them in old scripts.
17
17
18
18
The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. So we'll study the modern JavaScript modules from now on.
Copy file name to clipboardExpand all lines: 5-network/11-websocket/article.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -91,7 +91,7 @@ Sec-WebSocket-Version: 13
91
91
-`Origin` -- the origin of the client page, e.g. `https://javascript.info`. WebSocket objects are cross-origin by nature. There are no special headers or other limitations. Old servers are unable to handle WebSocket anyway, so there are no compatibility issues. But the `Origin` header is important, as it allows the server to decide whether or not to talk WebSocket with this website.
92
92
-`Connection: Upgrade` -- signals that the client would like to change the protocol.
93
93
-`Upgrade: websocket` -- the requested protocol is "websocket".
94
-
-`Sec-WebSocket-Key` -- a random browser-generated key for security.
94
+
-`Sec-WebSocket-Key` -- a random browser-generated key, used to ensure that the server supports WebSocket protocol. It's random to prevent proxies from caching any following communication.
95
95
-`Sec-WebSocket-Version` -- WebSocket protocol version, 13 is the current one.
96
96
97
97
```smart header="WebSocket handshake can't be emulated"
Here `Sec-WebSocket-Accept` is `Sec-WebSocket-Key`, recoded using a special algorithm. The browser uses it to make sure that the response corresponds to the request.
110
+
Here `Sec-WebSocket-Accept` is `Sec-WebSocket-Key`, recoded using a special algorithm. Upon seeing it, the browser understands that the server really does support the WebSocket protocol.
111
111
112
112
Afterwards, the data is transferred using the WebSocket protocol, we'll see its structure ("frames") soon. And that's not HTTP at all.
Copy file name to clipboardExpand all lines: README.md
+5-5Lines changed: 5 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# The Modern JavaScript Tutorial
2
2
3
-
This repository hosts the English content of the Modern JavaScript Tutorial, published in[https://javascript.info](https://javascript.info).
3
+
This repository hosts the English content of the Modern JavaScript Tutorial, published at[https://javascript.info](https://javascript.info).
4
4
5
5
## Translations
6
6
@@ -12,17 +12,17 @@ See <https://javascript.info/translate> for the details.
12
12
13
13
We'd also like to collaborate on the tutorial with other people.
14
14
15
-
Something's wrong? A topic is missing? Explain it to people, add as PR 👏
15
+
Something's wrong? A topic is missing? Explain it to people, add it as PR 👏
16
16
17
-
**You can edit the text in any editor.** The tutorial uses enhanced "markdown" format, easy to grasp. And if you want to see how it looks on-site, there's a server to run the tutorial locally at <https://github.com/javascript-tutorial/server>.
17
+
**You can edit the text in any editor.** The tutorial uses an enhanced "markdown" format, easy to grasp. And if you want to see how it looks on-site, there's a server to run the tutorial locally at <https://github.com/javascript-tutorial/server>.
18
18
19
19
The list of contributors is available at <https://javascript.info/about#contributors>.
20
20
21
21
## Structure
22
22
23
-
Every chapter, article or a task has its folder.
23
+
Every chapter, article, or task has its folder.
24
24
25
-
The folder is named like `N-url`, where `N` is a number for the sorting purposes and `url` is the URL part with title of the material.
25
+
The folder is named like `N-url`, where `N` is a number for the sorting purposes and `URL` is the URL part with the title of the material.
26
26
27
27
The type of the material is defined by the file inside the folder:
0 commit comments