What code newbies should know about the ...rest and ...spread syntax

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 of arguments 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 to b, and the third, fourth etc., will be stored in the rest parameter rest 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 using array methods like pop() , push()',sort(),filter()as well as any other operations that can be done on anarray`

  • 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 to firstName the second argument Takyi maps to lastName

  • The third and fourth arguments will be gathered into the bookTitles as an array

  • Because 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 like arguments.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 own this, they do not have the special arguments 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 parameters a, b and c we need to find a way to unpack the elements in the argsArr

  • The ...argsArr will now unpack the element into a list of arguments and then map each argument 2, 4 and 6 into the parameters a, b and c 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 the restaurant.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 the Chicken wings item to it

  • The 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 function getMenu

  • 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 the rest parameter or the spread 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 ❀️