The Three Dots of JavaScript: Rest and Spread Operator

Subscribe to my newsletter and never miss my upcoming articles

The ES2018 introduced us with the concept of the rest and spread operators. Though the ES2015 already introduced us the spread operator, ES2018 further expanded the syntax by adding spread properties to object literals. Both of them become very useful when we need to copy an array or object, or when we need to pass an indefinite amount of arguments into a function. Here, we'll discuss both the rest and spread operators.

The Rest Operator 💆‍♂️

Gif from Giphy

ES2018 introduced us the concept of rest operator. The rest operator looks like any regular argument except that it has three dots(...) in front of it. The rest operator will gather all the elements passed in the function argument and will create an array with it. Let's see it in action.

function letsRest(...args) {
    console.log(args);
}

letsRest(1, 2, 3, 4); // [1, 2, 3, 4]

We are passing the arguments as rest parameters with the help of ...args argument in the function definition. The parameters passed in the function will now create an array.

We can work with this array now. Any array methods can also be implemented in this array. And also, our function now can take an indefinite amount of arguments. Now, let's build a function with the help of rest parameters that will return the sum of all the arguments passed.

function sumAll(...args) {
    let sum = 0;
    for(let arg of args){
        sum = sum + arg;
    }
    return sum;
}

sumAll(1, 2, 3); //6
sumAll(1, 2, 3, 4); //10

We are using the rest operator to pass arguments and using a for-of loop to loop through all the elements and adding them into a variable sum. We can also pass regular parameters along with rest parameters in a function.

function iLove(name, ...items){
    console.log(`I am ${name}, and I love ${items}`)
}
iLove("nemo", "apple", "banana", "lemon") 
//I am nemo, and I love apple,banana,lemon

Here, we are combining normal parameters along with rest parameters. One thing to keep in mind when working with rest operators is that the argument with rest operator has to be the last argument passed. Because its job is to collect all the remaining arguments passed. So, the above example will work perfectly. But in the below code, we are passing a third argument after the rest parameter. This will return an error Uncaught SyntaxError: Rest parameter must be the last formal parameter.

function iLove(name, ...items, age){
    console.log(`I am ${name}, I am ${age} and I love ${items}`)
}
iLove("nemo", "apple", "banana", "lemon", 18);

The Spread Operator 🧈

Gif from Giphy

As the name suggests, the spread operator spreads the elements. It looks exactly like the rest operator. But, it works like a complement to the rest operator. The rest operator is defined in the function definition.

The spread operator will expand an array, string or object. Let's say, we want to clone all the values inside an array into a new one. Without the spread operator, we'll have to manually define all the values inside the new array like this,

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

Do you think this is an efficient solution? This needs a hell lot of writing. The spread operator makes it much easy to do such an operation.

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

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

We can also copy an array by simply using,

const arr3 = [...arr];

We can even clone an object with this syntax,

let obj = {
    1: 👩,
    2: 👨,
    3: 🧑
}
const obj2 = {...obj};

console.log(obj2); //{ 1: 👩, 2: 👨, 3: 🧑 }

Conclusion 🙇‍♂️

Both the rest and spread operator might seem confusing because both of them uses a ... syntax. So, how do we know where to use what? I remember it like this,

Rest Packs the Elements, Spread Unpacks the Elements.

Depending on your use case, you can choose which one you need.


If you liked this article, leave a ❤ and a comment. You can also follow me on twitter.

No Comments Yet