Table of Contents

Rest vs Spread operator

The rest operator (…) and the spread operator (…) in JavaScript are written the same way but are used for two different purposes.
Their usage depends on the context, and they perform opposite operations.

Rest Operator: Collects multiple elements into an array.
Spread Operator: Spreads the elements of an iterable out into individual elements.

Rest operator (...)

The rest operator is used to collect all remaining iterable elements into an array or object.

Usage in function arguments

This can be particularly useful in function signatures.

Example:

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
 
console.log(sum(1, 2, 3, 4, 5)); // Output: 15

Here, the …numbers argument takes all passed numbers and puts them into an array called numbers.

Rest function parameter should be the last one in the list:
function validFunction(param1, param2, ...rest) {
  console.log(param1, param2, rest);
}
A function cannot have multiple rest parameters.

Destructuring Arrays

You can use the rest operator to collect the rest of the elements into an array when destructuring:

const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(rest); // Output: [3, 4, 5]

Destructuring Objects

Similarly, when destructuring objects, the rest operator can collect the remaining own enumerable property keys into a new object:

const {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4};
console.log(rest); // Output: {c: 3, d: 4}

Clone Objects and Arrays

It's a handy way to create a shallow copy of an object or an array.

const obj = {a: 1, b: 2};
const clonedObj = {...obj}; // Output: {a: 1, b: 2}

Spread operator (...)

The spread operator is used to expand elements of an iterable (such as an array, object, or string) where zero or more arguments (for function calls), elements (for array literals), or key-value pairs (for object literals) are expected.

Example with Arrays

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // Output: [1, 2, 3, 4, 5]

Here, the …arr1 spreads out the elements of arr1, so they become individual elements in arr2.

Example with Objects

const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
console.log(obj2); // Output: { a: 1, b: 2, c: 3 }

Here, the …obj1 spreads out the properties of obj1, so they become individual properties in obj2.