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/05-data-types/10-destructuring-assignment/article.md
+57-30Lines changed: 57 additions & 30 deletions
Original file line number
Diff line number
Diff line change
@@ -2,19 +2,22 @@
2
2
3
3
The two most used data structures in JavaScript are `Object` and `Array`.
4
4
5
-
Objects allow us to create a single entity that stores data items by key, and arrays allow us to gather data items into an ordered collection.
5
+
- Objects allow us to create a single entity that stores data items by key.
6
+
- Arrays allow us to gather data items into an ordered list.
6
7
7
-
But when we pass those to a function, it may need not an object/array as a whole, but rather individual pieces.
8
+
Although, when we pass those to a function, it may need not an object/array as a whole. It may need individual pieces.
8
9
9
-
*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient. Destructuring also works great with complex functions that have a lot of parameters, default values, and so on.
10
+
*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient.
11
+
12
+
Destructuring also works great with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that.
10
13
11
14
## Array destructuring
12
15
13
-
An example of how the array is destructured into variables:
16
+
Here's an example of how an array is destructured into variables:
14
17
15
18
```js
16
19
// we have an array with the name and surname
17
-
let arr = ["Ilya", "Kantor"]
20
+
let arr = ["John", "Smith"]
18
21
19
22
*!*
20
23
// destructuring assignment
@@ -23,18 +26,22 @@ let arr = ["Ilya", "Kantor"]
23
26
let [firstName, surname] = arr;
24
27
*/!*
25
28
26
-
alert(firstName); //Ilya
27
-
alert(surname); //Kantor
29
+
alert(firstName); //John
30
+
alert(surname); //Smith
28
31
```
29
32
30
33
Now we can work with variables instead of array members.
31
34
32
35
It looks great when combined with `split` or other array-returning methods:
33
36
34
-
```js
35
-
let [firstName, surname] ="Ilya Kantor".split('');
37
+
```js run
38
+
let [firstName, surname] ="John Smith".split('');
39
+
alert(firstName); // John
40
+
alert(surname); // Smith
36
41
```
37
42
43
+
As you can see, the syntax is simple. There are several peculiar details though. Let's see more examples, to better understand it.
44
+
38
45
````smart header="\"Destructuring\" does not mean \"destructive\"."
39
46
It's called "destructuring assignment," because it "destructurizes" by copying items into variables. But the array itself is not modified.
40
47
@@ -69,26 +76,25 @@ In the code above, the second element of the array is skipped, the third one is
69
76
let [a, b, c] = "abc"; // ["a", "b", "c"]
70
77
let [one, two, three] = new Set([1, 2, 3]);
71
78
```
72
-
79
+
That works, because internally a destructuring assignment works by iterating over the right value. It's kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values.
73
80
````
74
81
75
82
76
83
````smart header="Assign to anything at the left-side"
In the previous chapter we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
93
99
94
100
We can use it with destructuring to loop over keys-and-values of an object:
@@ -107,62 +113,81 @@ for (let [key, value] of Object.entries(user)) {
107
113
}
108
114
```
109
115
110
-
...And the same for a map:
116
+
The similar code for a `Map` is simpler, as it's iterable:
111
117
112
118
```js run
113
119
let user = new Map();
114
120
user.set("name", "John");
115
121
user.set("age", "30");
116
122
117
123
*!*
124
+
// Map iterates as [key, value] pairs, very convenient for destructuring
118
125
for (let [key, value] of user) {
119
126
*/!*
120
127
alert(`${key}:${value}`); // name:John, then age:30
121
128
}
122
129
```
123
130
````
124
131
125
-
```smart header="Swap variables trick"
126
-
A well-known trick for swapping values of two variables:
132
+
````smart header="Swap variables trick"
133
+
There's a well-known trick for swapping values of two variables using a destructuring assignment:
127
134
128
135
```js run
129
136
let guest = "Jane";
130
137
let admin = "Pete";
131
138
132
-
// Swap values: make guest=Pete, admin=Jane
139
+
// Let's swap the values: make guest=Pete, admin=Jane
140
+
*!*
133
141
[guest, admin] = [admin, guest];
142
+
*/!*
134
143
135
144
alert(`${guest} ${admin}`); // Pete Jane (successfully swapped!)
136
145
```
137
146
138
147
Here we create a temporary array of two variables and immediately destructure it in swapped order.
139
148
140
149
We can swap more than two variables this way.
141
-
150
+
````
142
151
143
152
### The rest '...'
144
153
145
-
If we want not just to get first values, but also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`:
154
+
Usually, if the array is longer when the list at the left, the "extra" items are omitted.
155
+
156
+
For example, here only two items are taken, and the rest is just ignored:
146
157
147
158
```js run
148
-
let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*];
159
+
let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
149
160
150
161
alert(name1); // Julius
151
162
alert(name2); // Caesar
163
+
// Furher items aren't assigned anywhere
164
+
```
165
+
166
+
If we'd like also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`:
167
+
168
+
```js run
169
+
let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*];
152
170
153
171
*!*
154
-
//Note that type of `rest` is Array.
172
+
//rest is arrayofitems, starting from the 3rd one
155
173
alert(rest[0]); // Consul
156
174
alert(rest[1]); // of the Roman Republic
157
175
alert(rest.length); // 2
158
176
*/!*
159
177
```
160
178
161
-
The value of `rest` is the array of the remaining array elements. We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignment.
179
+
The value of `rest` is the array of the remaining array elements.
180
+
181
+
We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignment.
182
+
183
+
```js run
184
+
let [name1, name2, *!*...titles*/!*] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
185
+
// now titles = ["Consul", "of the Roman Republic"]
186
+
```
162
187
163
188
### Default values
164
189
165
-
If there are fewer values in the array than variables in the assignment, there will be no error. Absent values are considered undefined:
190
+
If the array is shorter than the list of variables at the left, there'll be no errors. Absent values are considered undefined:
Default values can be more complex expressions or even function calls. They are evaluated only if the value is not provided.
189
214
190
-
For instance, here we use the `prompt` function for two defaults. But it will run only for the missing one:
215
+
For instance, here we use the `prompt` function for two defaults:
191
216
192
217
```js run
193
218
// runs only prompt for surname
@@ -197,7 +222,7 @@ alert(name); // Julius (from array)
197
222
alert(surname); // whatever prompt gets
198
223
```
199
224
200
-
225
+
Please note: the `prompt` will run only for the missing value (`surname`).
201
226
202
227
## Object destructuring
203
228
@@ -209,9 +234,9 @@ The basic syntax is:
209
234
let {var1, var2} = {var1:…, var2:…}
210
235
```
211
236
212
-
We have an existing object at the right side, that we want to split into variables. The left side contains a "pattern" for corresponding properties. In the simple case, that's a list of variable names in `{...}`.
237
+
We should have an existing object at the right side, that we want to split into variables. The left side contains a "pattern" for corresponding properties.
213
238
214
-
For instance:
239
+
Usually, that's a list of variable names in `{...}`, for instance:
215
240
216
241
```js run
217
242
let options = {
@@ -229,7 +254,9 @@ alert(width); // 100
229
254
alert(height); // 200
230
255
```
231
256
232
-
Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. The order does not matter. This works too:
257
+
Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables.
The pattern on the left side may be more complex and specify the mapping between properties and variables.
240
267
241
-
If we want to assign a property to a variable with another name, for instance, `options.width`to go into the variable named `w`, then we can set it using a colon:
268
+
If we want to assign a property to a variable with another name, for instance, make `options.width` go into the variable named `w`, then we can set the variable name using a colon:
0 commit comments