What code newbies should know about the ...rest and ...spread syntax
Hello World π, Akwaaba, in this post, we take a look at JavaScript's three dots ...
, the rest parameter, and the spread operator.
The objective is to learn how to pass an indefinite number of arguments to a function and how to pass arrays to functions as parameters. using rest
and spread
respectively.
Let's get started. πΆ
What is the rest parameter?
The rest parameter collects the remaining elements into an array.
Use Case
We can use the rest
parameter to gather parameters and put all of them into an array.
It allows you to represent an indefinite number of arguments
into an array
.
We define the rest
parameter with three dots preceding the variable
name. Eg. ...others
.
Before we dive deeper, let's see how to use the rest
parameter on an array destructuring
Generally, the destructuring assignment helps to extract values from an array
or object
and then collect or gather the remaining elements.
Using the rest parameter in array
destructuring
In the code below, we extract two elements from an array
and gather the remaining elements into ...others
π
const arr = [1, 2, 3, 4, 5 ];
const [a, b, ...others] = arr; /*Extract the first two items in the array into the variables, a and b */
console.log(a,b);
/* 1, 2 */
console.log(others); /* Remaining elements */
/* [3, 4, 5] */
Using the rest parameter in object destructuring
In the code below, we will extract only the first value of the object weekDays
, then gather the remaining values into restOfDays
π
let weekDays = {day1: "Monday", day2: "Tuesday", day3: "Wednesday", day4: "Thursday", day5: "Friday"};
const {day1, ...restOfDays} = weekDays;
console.log(restOfDays);
The output will be
{day2: "Tuesday", day3: "Wednesday", day4: "Thursday", day5: "Friday"}
Function rest parameter.
Let's take a look at how to use the rest
parameter on functions
.
A
function
can have unspecified number ofarguments
passed to it, this can be achieved by prefixing...
before the parameter name. Eg....args
.
Use Case
In this situation, we pass some arguments
to a function
call but we only need to use a specific number of arguments and gather the unspecified arguments into an array
The rest
parameter therefore allows you to represent an indefinite number of arguments as an array
The advantage, with this approach is, you can now take the returned array
and perform any required operations on it.
Confused π, let's take a look at the code below to understand what is happening. π
function sum(a,b){
return a + b;
}
console.log(sum(1,2,3,4,5))
There will be no error even though we have excess arguments
In the result only the first two arguments will be counted, the rest of the arguments will simply be ignored.
So, how do we get the remaining arguments passed to the function ?
The remaining arguments can be included in the function definition by using three dots ...
followed by the name of the array
to contain them.
The ...
literally gather the remaining parameters
into an array
We can now rewrite the code above as
function sum(a,b, ...rest){
console.log(a + b);
console.log(rest); /* gather the remaining parameters into the array */
}
sum(1,2,3,4,5)
The output of the rest
will then be
[3, 4, 5]
Now, using the rest parameter ...
as part of the names listed in the function definition, we can later invoke or call the function
with unlimited number of arguments and you will not get any errors because of the 'excessive' arguments.
The arguments you pass to the function will map to the parameter list.
The first argument maps to
a
, the second one maps tob
, and the third, fourth etc., will be stored in the rest parameterrest
as an array.
The rest parameter must be defined at the end
When declaring the parameters in your function definition, and you want to add the rest parameter(...
), it must be the last* of all the parameters.
What is so special about the rest parameter ?
Because the rest parameter returns an
array
; it becomes easier to manipulate its values usingarray methods
likepop()
,push()',
sort(),
filter()as well as any other operations that can be done on an
array`We can even iterate all the elements in the array and perform the needed operation on it.
Let's see an example on using the elements in the array
, π
function showName(firstName, lastName, ...bookTitles) {
console.log( firstName + ' ' + lastName ); /* Robert Takyi */
/* the rest go into bookTitles array */
/* i.e. bookTitles = ["JavaScript made easy", "Imperfect coding"] */
/*We can now use the elements in the array */
console.log( bookTitles[0] ); /* JavaScript made easy */
console.log( bookTitles[1] ); /* Imperfect coding */
console.log( bookTitles.length ); /* 2 */
}
/*pass the arguments to the function parameters */
showName("Robert", "Takyi", "JavaScript made easy", "Imperfect coding");
The first argument
Robert
maps tofirstName
the second argumentTakyi
maps tolastName
The third and fourth arguments will be gathered into the
bookTitles
as an arrayBecause we have a
bookTitles
array we can then perform any operation on it.
Rest vs Arguments keyword
Before the rest parameter existed, to get all the arguments
of a function
we use the arguments
keyword which is an array-like
object.
The Arguments variable
Is a special array-like object named arguments that contains all arguments by their index.
The arguments
object is initiated during the function execution
Let's take our previous showName
function, not pass it any parameter and try accessing the arguments
variable.
Look at the code below π
function showName() {
console.log(arguments); /*This is the array-like object returned */
showName("Robert", "Takyi", "JavaScript made easy", "Imperfect coding");
The output will be
Arguments(4) ["Robert", "Takyi", "JavaScript made easy", "Imperfect coding", callee: Ζ, Symbol(Symbol.iterator): Ζ]
0: "Robert"
1: "Takyi"
2: "JavaScript made easy"
3: "Imperfect coding"
callee: Ζ showName()
length: 4
Symbol(Symbol.iterator): Ζ values()
__proto__: Object
}
Before the introduction of the rest
parameter, the arguments
variable was the only way to get all the arguments of a function .
Though it is still used in some old code base, there are some downsides:
Even though the
arguments
is array-like and iterable, it is not a real array, meaning you can not perform array method likearguments.map(...)
or arguments.filter(...) on it.If we try to access the
arguments
object from an arrow function, it takes it from the outside function. Because arrow function do not have their ownthis
, they do not have the specialarguments
object either.
In summary, we use the JavaScript rest parameter to represent an indefinite number of arguments as an array.
The Spread syntax.
We have just learnt how to get an array
from a list of paramters
, what if we need to do exactly the reverse π that is to unpack the elements in an array.
The spread operator allows us to expand elements. It helps us to unpack elements in an array into individual arguments.
The spread
syntax is also very similar to the rest
syntax, it uses the ...
. Let's take a look at some use cases.
Adding elements into an existing array
To add elements into an existing array, you can "spread" the elements: meaning you unpack the elements in the array and you spread the individual elements into the existing array.
Let's see how that can be done
const arr = ["Emma","Akosua","Esenam"];
const newArr = ["Timothy", ...arr] /*using the spread operator ...arr */
console.log(newArr);
We take out the individual elements in the array and then spread into into the
newArr
The
newArr
now contains all the elements of the array. The output will be
["Timothy", "Emma", "Akosua", "Esenam"]
Merging arrays
We can use the spread
syntax , ...
to merge arrays. Lets take a look at the code below :
const arr1 = ["Emma","Akosua","Esenam"];
const arr2 = ["Felix","Kwasi","Tim","Ama"];
/* use the spread syntax to unpack the individual elements of both arrays and merge
it into one array */
const mergedArrays = [...arr1, ...arr2];
console.log(mergedArrays);
The output will be
["Emma", "Akosua", "Esenam", "Felix", "Kwasi", "Tim", "Ama"]
Copying arrays
We can also use the spread
syntax to copy arrays.
See the code below
const iniArr = ["Emma","Akosua","Esenam"];
const copyArr = [...iniArr];
console.log(copyArr);
/* ["Emma", "Akosua", "Esenam"] */
The above copies iniArr
into copyArr
, now we can do things on copyArr
and any operation performed on copyArr
will not have any effect on iniArr
.
Pass elements of an array to function
Supposing we have an array
that we want to pass as a list of arguments
in a function, we can use the spread
operator to achieve that.
The code below shows how
function sum(a, b, c,){
return a + b + c;
}
const argsArr = [2,4, 6];
console.log(sum(...argsArr));
Because we want to map the individual elements of the array
argsArr
into the parametersa
,b
andc
we need to find a way to unpack the elements in theargsArr
The
...argsArr
will now unpack the element into a list of arguments and then map each argument2
,4
and6
into the parametersa
,b
andc
respectively.The returned value will now be
12
Example two
Let's assume we have a restaurant object
, which contains the name and location of the restaurant as well as the main menu being served at the restaurant.
Your task is to
- Add one more menu , chicken wings, to the main menus
- Pass the menus as an array to a function and display the menus
Let's see how to achieve that using the spread
operator.
let restaurant = {
name: "Classic taste",
location: "Accra",
mainMenu :['Pizza', 'Pasta', 'Risotto']
}
/* task one add one more menu "chicken wings" to the main menu */
/* unpack the items into individual items and copy into new array */
let newMenu = [...restaurant.mainMenu, "Chicken wings"];
console.log(newMenu) /* ["Pizza", "Pasta", "Risotto", "Chicken wings"] */
/*pass newMenu to the function */
function getMenu(...items){
console.log(`We have on the menu: ${items}`)
}
/*Call the function */
getMenu(....newMenu);
/* We have on the menu: Pizza,Pasta,Risotto,Chicken wings */
Let's break down what is happening in the code above,
First, we accessed the
mainMenu
array using therestaurant.mainMenu
Then, we unpacked the individual items in the array using the spread operator
...restaurant.mainMenu
We copied these individual items into a new array
newMenu
and then added theChicken wings
item to itThe
newMenu
now contains an array of["Pizza", "Pasta", "Risotto", "Chicken wings"]
We now unpacked the items in
newMenu
array and pass its as an argument when into a functiongetMenu
We now have access to the individual items so we console it
Using the spread operator on strings
The spread
operator can be used on strings
to get the individual characters in a string
.
let str = "emmanuel";
/* spread into individual characters */
let newStr = [...str];
console.log(newStr);
/*["e", "m", "m", "a", "n", "u", "e", "l"] */
Copying objects
The spread syntax can also be used to copy objects
. Let's take a look, in the code below, we copied an object obj
into another object with has an existing property age: 34
let obj = {firstName: "Emman", lastName: "Kumah"};
let objCopy = {...obj, age: 34};
console.log(objCopy);
/*{firstName: "Emman", lastName: "Kumah", age: 34} */
When we copy an object into another object, modifying the initial object does not modified the copied object.
Summary
To recap all that we have learnt
- When we see
...
in a code, then it is either therest
parameter or thespread
syntax - When
...
is at the end of function parameters, itβs βrest parametersβ and gathers the rest of the list of arguments into an array - When
...
occurs in a function call or alike, itβs called a βspread syntaxβ and expands an array into a list - Rest parameters are used to create functions that accept any number of arguments
- The spread syntax is used to pass an array to functions that normally require a list of many argument
Use patterns: Rest parameters are used to create functions that accept any number of arguments. The spread syntax is used to pass an array to functions that normally require a list of many arguments.
Did you find my article insightful, please help spread the word by sharing on your social platforms. I would also love to read comments and feedback from you. Me daa se
PS: Akwaaba and Me daa se are Ghanaian π¬π dialect meaning, Welcome and Thank you respectively β€οΈ