Skip to main content

Command Palette

Search for a command to run...

Spread and Rest Operators in JavaScript

Updated
•4 min read•View as Markdown

Spread and Rest operators are those types of features that you would need some hands-on experience rather than some flowery words to understand their importance. Providing very elegant functionalities, this syntax of JavaScript is in popular use because of its simplicity and convenience.

The Rest Operator

The word 'rest', as this operator's name has the same context as it does in this statement: 'Bring me the rest of the stuff!' As rude as this sounds, it solves a very important problem, especially in function arguments.

Suppose you are given a task to write a function to sum all numbers passed in a function. Normally, one would expect the user to pass an array, but as we know, we can never trust the user, and it would be pretty hectic for the user to convert their arguments into an array. The user wants to use the function as:

sum(1,2)
sum(1,2,3)
sum(1,2,3,4)
// And So on...

So, as a developer, what can we do? This is where the rest operator comes in.

We can write:

function sum(a,b,...rest){
  if(Number.isNaN(a) || Number.isNaN(b) throw new Error('Not enough arguments');
  const sum = a+b+rest.reduce((sum,element)=>sum+element,0);
  return sum;
}

The syntax here is basically: a and b will accept the first two arguments. This is because we need at least 2 elements, which, if we don't get, we can throw an error.

Now the next argument is (...) followed by a variable name (the rest is the name of the variable in this case), which will accept all the other arguments and store them as an array. The (...) is called the rest operator in this case.

It is important to note that the same representation (...) is used for the spread operator too, so what these 3 dots refer to depends on the context of the code.

It can also be used to collect all the variables by using it directly:

function sum(...rest){
  return rest.reduce((sum,element)=>sum+element,0);
}

Another popular use case is to store a segment of an array or object as a new array/object during destructuring. For example:

const arr = [1,2,3,4,5];
const [a,b,...rest] = arr;
// Here a=1 b=2 and rest=[3,4,5]

Similarly for Objects:

const obj = {a:1,b:2,c:3,d:4,e:5};
const {a,c,d,...rest} = obj

// Here a=1,c=3,d=4 and rest = {b:2,e:5}

In the above example, I specifically took the elements in a random order. This is because I wanted to show that in objects, properties do not need to be destructured in any order.

The Spread Operator

The spread operator, as the name implies, spreads or releases the values of the contents of the given object or array. Denoted with the same 3 dots (...), it is called a spread operator when it is used in a particular context. For example:

const arr = [1,2,3];
const longer = [...arr,4,5];
// Now Longer = [1,2,3,4,5];

const obj = {a:1,b:2};
const longObj = {...obj,c:3};
// longObj = {a:1,b:2,c:3};

It can be used to spread, merge, clone or combine arrays or objects.

Cloning

const arr = [1,2,3];
const copyArr = [...arr];

const obj =  {a:1,b:2,c:3};
const copyObj = {...obj}

Here, in the case of both objects and arrays, they have the same values as the element they copied from. However, the primary difference is that the 2 entities don't point to the same object in memory but are 2 different objects in different memory locations that have the same value.

For example, if we did:

const arr = [1,2,3];
const copyArr = arr;
//Same for object

Then, modifying the copyArr, say with the pop operation, would modify the original array too. But in the previous method, copying by the spread operator, there is no such risk.

Merging

The spread operator can be used to merge two or more arrays or objects.

Arrays:

const arr1 =[1,2];
const arr2 =[3,4];
const arr3 =[5,6];

const combined = [...arr1,...arr2,...arr3];
//Results in combined = [1,2,3,4,5,6];

Objects:

const obj1 ={a:1,b:2};
const obj2 ={c:3,d:4};
const obj3 ={e:5,f:6};

const combinedObj = {...obj1,...obj2,...obj3};
//Results in combinedObj = {a:1,b:2,c:3,d:4,e:5,f:6};

Utilising this syntax can help us get really fast at basic operations and make us better developers while also providing comfort in writing code.