Javascript Spread and Rest Operator

Overview

The ... is the spread syntax that allows you to specify an array that should be split and have its items passed in as separate arguments to a function.

According to the MDN

The spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

Syntax

let arr = [1,2,3,4,5];

function multiply(a, b, c, d, e){
  return a * b * c * d * e;
}

//Spreads the array as separate parameters
console.log(multiply(...arr));   //120

Example

Consider a scenario where we have to find the largest number from the given array of numbers. The ideal solution will be to use Math.max with apply method.

let arr = [1, 2, 3, 4, 5];
console.log(Math.max.apply(null, arr)); // 5

This solution works perfect but it is bit confusing. ES6 ... spread operator makes this very easy and simple.

let arr = [1, 2, 3, 4, 5];
console.log(Math.max(...arr)); // 5

Javascript engine splits arr into individual arguments.

Combining multiple arrays

With javascript ... spread operator it is easy to combine multiple arrays.

let arr = [1, 2, 3, 4, 5];
let arr2 = [6, 7, 8, 9, 10];

let combine = [...arr, ...arr2]; 
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let combine2 = [0, ...arr, 11, ...arr2, 12]; 
//[0, 1, 2, 3, 4, 5, 11, 6, 7, 8, 9, 10, 12]

let combine3 = [...arr,'prashant',...arr2]; 
//[1, 2, 3, 4, 5, "prashant", 6, 7, 8, 9, 10]

The ... spread operator allows us to pass all the items of arr and arr2 at the same time add extra items also.

Copying an array

Drawbacks while copying arrays before ... spread operators.

let arr = [1, 2, 3, 4, 5];
let copy = arr;
console.log(copy);
//[1, 2, 3, 4, 5]

arr.push(6);
console.log(arr);
//[1, 2, 3, 4, 5, 6]

console.log(copy);
//[1, 2, 3, 4, 5, 6]

We have added an extra item to arr with arr.push(6) but the same gets updated in copy, this happens because arr is never copied to copy but passed as the reference which means copy is just pointing to arr. A separate solution would be to copy all the items individually using loops.

We can solve this issue with the javascript ... spread operator.

let arr = [1, 2, 3, 4, 5];
let copy = [...arr];
console.log(copy);
//[1, 2, 3, 4, 5]

arr.push(6);
console.log(arr);
//[1, 2, 3, 4, 5, 6]

console.log(copy);
//[1, 2, 3, 4, 5]

Use with Constructors

It is not possible to directly use an array and apply with new keyword while declaring constructor. But with the javascript ... spread operator we can do this easily.

let dateFields = [1970, 0, 1];  
let d = new Date(...dateFields);
console.log(d);
//Thu Jan 01 1970 00:00:00 GMT+0530 (India Standard Time)

Use with Funcitons

With the introduction of ... spread operators in ES6 we can now replace the apply() method to pass the arrays of arguments to functions.

let example = (a, b, c, d = 1) => {
  return a * b * c * d;
}
let arr = [1, 2, 3 , 4, 5];

//Before ... spread operators
console.log(example.apply(null, arr)); // 24

//After ... spread operators
console.log(example(...arr)); // 24

Array is split into the parameters and automatically passed by the javascript engine. Extra parameters are ignored.


Rest Parameters

Overview

Rest parameters are exactly opposite of spread operator. Spread operator is used to expand all the items of the arrays while Rest parameters is used to condense different items to form an array.
Rest parameters are also indicated with ... in javascript.

let arr = [1, 2, 3, 4, 5, 6, 7, 8];
const [first, second, ...remaining] = arr;
console.log(first);
// 1
console.log(second);
// 2
console.log(remaining);
// [3, 4, 5, 6, 7, 8]

The destructuring removed the first and second item and added the remaining items to the rest parameters ...remaining.

Rest parameters with Functions.

The rest parameters are ideally used with functions instead of arguments object as it has many limitations.

let addAll = (...args) => {
  return args.reduce((a, b) => {return a + b});
}

console.log(addAll(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
//55

Difference between arguments and Rest parameters

  • arguments objects are not real arrays they are just array like objects which have only one property length, Where as Rest parametes are real arrays which has all methods like pop, forEach, push etc.
  • For arguments objects we cannot use different names while with the Rest parameters we can use our custom names.
function multiply(d, ...everything){
  return everything.map(e => d * e);
}

console.log(multiply(2, 1, 2, 3, 4, 5, 6, 7, 8));
//[2, 4, 6, 8, 10, 12, 14, 16]

Leave a Reply

Your email address will not be published. Required fields are marked *