Skip to content

Commit 24dc611

Browse files
authored
Merge pull request #132 from odsantos/fix-advanced-functions
Update 06-rest-parameters
2 parents 8337d91 + 6bfbb33 commit 24dc611

File tree

1 file changed

+62
-18
lines changed
  • 1-js/06-advanced-functions/02-rest-parameters-spread

1 file changed

+62
-18
lines changed

1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md renamed to 1-js/06-advanced-functions/02-rest-parameters-spread/article.md

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Rest parameters and spread operator
1+
# Rest parameters and spread syntax
22

33
Many JavaScript built-in functions support an arbitrary number of arguments.
44

@@ -8,7 +8,7 @@ For instance:
88
- `Object.assign(dest, src1, ..., srcN)` -- copies properties from `src1..N` into `dest`.
99
- ...and so on.
1010

11-
In this chapter we'll learn how to do the same. And, more importantly, how to feel comfortable working with such functions and arrays.
11+
In this chapter we'll learn how to do the same. And also, how to pass arrays to such functions as parameters.
1212

1313
## Rest parameters `...`
1414

@@ -25,7 +25,7 @@ alert( sum(1, 2, 3, 4, 5) );
2525

2626
There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted.
2727

28-
The rest parameters can be mentioned in a function definition with three dots `...`. They literally mean "gather the remaining parameters into an array".
28+
The rest of the parameters can be included in the function definition by using three dots `...` followed by the name of the array that will contain them. The dots literally mean "gather the remaining parameters into an array".
2929

3030
For instance, to gather all arguments into array `args`:
3131

@@ -96,9 +96,7 @@ showName("Julius", "Caesar");
9696
showName("Ilya");
9797
```
9898

99-
In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function, no matter their total number.
100-
101-
And it still works, we can use it today.
99+
In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function. And it still works, we can find it in the old code.
102100

103101
But the downside is that although `arguments` is both array-like and iterable, it's not an array. It does not support array methods, so we can't call `arguments.map(...)` for example.
104102

@@ -119,11 +117,12 @@ function f() {
119117

120118
f(1); // 1
121119
```
122-
````
123120

124121
As we remember, arrow functions don't have their own `this`. Now we know they don't have the special `arguments` object either.
122+
````
125123
126-
## Spread operator [#spread-operator]
124+
125+
## Spread syntax [#spread-syntax]
127126
128127
We've just seen how to get an array from the list of parameters.
129128
@@ -149,7 +148,7 @@ alert( Math.max(arr) ); // NaN
149148
150149
And surely we can't manually list items in the code `Math.max(arr[0], arr[1], arr[2])`, because we may be unsure how many there are. As our script executes, there could be a lot, or there could be none. And that would get ugly.
151150
152-
*Spread operator* to the rescue! It looks similar to rest parameters, also using `...`, but does quite the opposite.
151+
*Spread syntax* to the rescue! It looks similar to rest parameters, also using `...`, but does quite the opposite.
153152
154153
When `...arr` is used in the function call, it "expands" an iterable object `arr` into the list of arguments.
155154
@@ -170,7 +169,7 @@ let arr2 = [8, 3, -8, 1];
170169
alert( Math.max(...arr1, ...arr2) ); // 8
171170
```
172171
173-
We can even combine the spread operator with normal values:
172+
We can even combine the spread syntax with normal values:
174173
175174
176175
```js run
@@ -180,7 +179,7 @@ let arr2 = [8, 3, -8, 1];
180179
alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25
181180
```
182181
183-
Also, the spread operator can be used to merge arrays:
182+
Also, the spread syntax can be used to merge arrays:
184183
185184
```js run
186185
let arr = [3, 5, 1];
@@ -193,17 +192,17 @@ let merged = [0, ...arr, 2, ...arr2];
193192
alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2)
194193
```
195194
196-
In the examples above we used an array to demonstrate the spread operator, but any iterable will do.
195+
In the examples above we used an array to demonstrate the spread syntax, but any iterable will do.
197196
198-
For instance, here we use the spread operator to turn the string into array of characters:
197+
For instance, here we use the spread syntax to turn the string into array of characters:
199198
200199
```js run
201200
let str = "Hello";
202201
203202
alert( [...str] ); // H,e,l,l,o
204203
```
205204
206-
The spread operator internally uses iterators to gather elements, the same way as `for..of` does.
205+
The spread syntax internally uses iterators to gather elements, the same way as `for..of` does.
207206
208207
So, for a string, `for..of` returns characters and `...str` becomes `"H","e","l","l","o"`. The list of characters is passed to array initializer `[...str]`.
209208
@@ -221,24 +220,69 @@ The result is the same as `[...str]`.
221220
But there's a subtle difference between `Array.from(obj)` and `[...obj]`:
222221
223222
- `Array.from` operates on both array-likes and iterables.
224-
- The spread operator operates only on iterables.
223+
- The spread syntax works only with iterables.
225224
226225
So, for the task of turning something into an array, `Array.from` tends to be more universal.
227226
228227
228+
## Get a new copy of an array/object
229+
230+
Remember when we talked about `Object.assign()` [in the past](https://javascript.info/object#cloning-and-merging-object-assign)?
231+
232+
It is possible to do the same thing with the spread syntax.
233+
234+
```js run
235+
let arr = [1, 2, 3];
236+
let arrCopy = [...arr]; // spread the array into a list of parameters
237+
// then put the result into a new array
238+
239+
// do the arrays have the same contents?
240+
alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true
241+
242+
// are the arrays equal?
243+
alert(arr === arrCopy); // false (not same reference)
244+
245+
// modifying our initial array does not modify the copy:
246+
arr.push(4);
247+
alert(arr); // 1, 2, 3, 4
248+
alert(arrCopy); // 1, 2, 3
249+
```
250+
251+
Note that it is possible to do the same thing to make a copy of an object:
252+
253+
```js run
254+
let obj = { a: 1, b: 2, c: 3 };
255+
let objCopy = { ...obj }; // spread the object into a list of parameters
256+
// then return the result in a new object
257+
258+
// do the objects have the same contents?
259+
alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // true
260+
261+
// are the objects equal?
262+
alert(obj === objCopy); // false (not same reference)
263+
264+
// modifying our initial object does not modify the copy:
265+
obj.d = 4;
266+
alert(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4}
267+
alert(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3}
268+
```
269+
270+
This way of copying an object is much shorter than `let objCopy = Object.assign({}, obj);` or for an array `let arrCopy = Object.assign([], arr);` so we prefer to use it whenever we can.
271+
272+
229273
## Summary
230274
231-
When we see `"..."` in the code, it is either rest parameters or the spread operator.
275+
When we see `"..."` in the code, it is either rest parameters or the spread syntax.
232276
233277
There's an easy way to distinguish between them:
234278
235279
- When `...` is at the end of function parameters, it's "rest parameters" and gathers the rest of the list of arguments into an array.
236-
- When `...` occurs in a function call or alike, it's called a "spread operator" and expands an array into a list.
280+
- When `...` occurs in a function call or alike, it's called a "spread syntax" and expands an array into a list.
237281
238282
Use patterns:
239283
240284
- Rest parameters are used to create functions that accept any number of arguments.
241-
- The spread operator is used to pass an array to functions that normally require a list of many arguments.
285+
- The spread syntax is used to pass an array to functions that normally require a list of many arguments.
242286
243287
Together they help to travel between a list and an array of parameters with ease.
244288

0 commit comments

Comments
 (0)