Signup/Sign In

Rest Parameter and Spread Operator in JavaScript ES6

Posted in Programming   LAST UPDATED: JULY 4, 2023

    Functions play an important role in functional JavaScript. This leads to reusable code and avoids DRY(Do not Repeat Yourself) coding guidelines.

    These functions can be user-defined or built-in functions. Functions accept arguments that can be passed by calling functions and called functions do perform some operation using these arguments based on the requirement.

    In this article, we will see how Rest Parameters and Spread Operator in JavaScript can b helpful when we follow the functional programming guidelines.

    To give you an idea, Rest and Spread operators were introduced in ECMAScript 5 or ES6 version of JavaScript and have since gained popularity with developers around the globe using it more and more while coding. So let's see how these can be implemented.

    Rest and Spread Operator in JavaScript


    Function arguments in JavaScript

    As I mentioned earlier, built-in functions and user-defined functions expect arguments to be passed to them(although this is not mandatory, but generally, yes). Let us take Math.max() function which is a built-in function and accepts arguments to return the maximum value out of the passed arguments like,

    Math.max(1, 2, 4);    // will return 4 as the maximum value

    Now the problem here is that you need to pass arguments from which the function will find the maximum and return to us. But, what if we have to find the maximum out of 3 numbers once and then the next time we have to find the maximum out of 4 numbers, or out of 5 numbers To accommodate such functionality we will have to make changes to our code every time we call the Math.max() function because we are not sure about the number of arguments as they are constantly changing. Such a situation can be very well handled using Rest Parameters. But first let's see another solution to the above problem, which is using the arguments variable.


    arguments variable in function

    As we mentioned earlier, we can write our own functions in JavaScript which are known as user-defined functions. So, each function has an argument object which contains all passed parameters. Arguments passed to function can be accessed using index-like accessing elements.

    function names() 
    {
        console.log(arguments.length, arguments[0], arguments[1]);
    }
    
    //prints 2 "Sridhar" "Belide"
    names("Sridhar", "Belide");

    Note: arguments variable only has length property for the array that it is and does not support any other array methods like map, sort, filter and more. But we can access the values stored in the arguments variable by using the index, as we have done in the example above.


    What is Rest Parameter in JavaScript

    In the section above, we have seen how arguments an array/variable is passed to any function, how to access them, and when to use it. But arguments variable is not always recommended and there are a few problems or additional steps that we have to perform which can be avoided if we use the Rest parameter.

    Rest parameters allow you to pass arguments as an array to a function. You must be wondering if the arguments variable was doing the same thing but in the case of arguments variable the values are stored just like an array, but as mentioned in the section above it is not an actual array and values can be accessed using index values only, whereas, in the case of Rest parameters, values are actually gathered into an array and passed to the function. Let's try to understand the difference with some code examples.

    Find sum of numbers without Rest Parameter

    Let us take a simple example to find the sum of numbers passed to a function using the arguments variable. There are many ways to do this, but we will be creating an array using the arguments variable and then loop around the array values using the forEach loop and add the values to return the result,

    function findSum()
    {
        // creating array from arguments value
        var numbers = Array.prototype.slice.call(arguments);
        sum = 0;
        // loop around the array and add the values
        numbers.forEach(function(number)
        {
            sum += number;     
        });
        return sum;
    }
    
    console.log(findSum(1, 2, 3));    // 6

    In the code above, we have converted arguments variable to an array using Array.prorotype.slice.call() and assigned it to the numbers variable, which is then looped and we performed the required operation on the value.

    Find sum of numbers with the Rest Parameter

    Now, let us see how the above-mentioned function for finding out the sum of numbers can be implemented using Rest Parameters.

    function findSum(...numbers)
    {
        var sum = 0;
        numbers.forEach(function(number)
        {
            sum += number;     
        });
        return sum;
    }
    
    console.log(findSum(1, 2, 3));    // 6

    The syntax for using rest parameters is 3 dots ... followed by a name(a variable name which is an array), hence it is also called a named parameter. In the above example, numbers is preceded by 3 dots ... which is a rest parameter.

    The rest parameter is an array and all array methods can be applied to it. So in the code above, we used forEach() to iterate and found the sum of numbers. numbers as the named parameter will have all the arguments passed to it in the form of an array.

    Apart from all the array functions that are available when we use rest parameters, we also save one line of code where we convert the arguments variable into an array.

    The rest parameter must be at the end

    One important rule to remember while using the rest parameter is that it should always be used as the last argument in a function, or else you will get a syntax error.

    If you pass a few arguments to any function including the rest parameter, then the rest parameter will receive all remaining arguments starting from its position. For example,

    // function with 2 normal parameters and 1 rest parameter
    function allDomains(domainName, mainExtention, ...extensions)
    {
        console.log(domainName+ ' '+ mainExtention);    // Studytonight.com
        console.log(extensions);    // [".xyz", ".online", ".in"]
        console.log(extensions[0]);    // ".xyz"
        console.log(extensions[1]);    // ".online"
        console.log(extensions[2]);    // ".in"
        console.log(extensions.length);    // 3
    }
    
    console.log(allDomains("Studytonight", ".com", ".xyz", ".online", ".in"));

    Here, domainName and mainExtension received the values Studytonight and .com and all the other remaining arguments(3 in our case) were received as rest parameters in the extensions array.

    As we mentioned earlier, rest parameters should always be the last parameter for a function, therefore in the code example below, you will get a syntax error.

    function findSum(a, ...numbers, b)
    {
        // Error: Rest parameter must be last formal parameter
        var sum = 0;
        numbers.forEach(function(number)
        {
            sum += number;     
        });
        return sum;
    }


    What is Spread Operator in JavaScript?

    We have seen the rest parameter converting individual arguments passed to a function into an array, in this section we will learn about the spread operator. The Spread operator does the exact opposite of what the rest parameters did. It is used to convert an array into individual array elements.

    Let us take an example of the Math.max() built-in function which returns the maximum number out of the passed arguments. So, we need to pass arguments individually,

    Math.max(1, 2, 3)   // returns 3 as maximum

    But, let us say we have an array of numbers like [1, 2, 3, 4, 5] and we want to find the maximum value stored in the array, then how will we do it? You cannot pass an array directly to Math.max() as that would give NaN a result.

    Math.max([1,2,3,4,5])    // returns NaN

    The only available option is that you must pass the array elements individually as separate arguments to the Math.max() function like,

    Math.max(arr[0], arr[1], ...)

    The problem with the above approach is that you never know how many elements are available in an array. Hence, this is not the preferable way to do it. So what do we do?

    Yes, you are right, here comes the spread operator to our rescue.

    var arr = [1, 2, 3, 4, 5];
    /* 
        providing the array as an argument
        preceded by 3 dots ...
    */
    var max = Math.max(...arr);
    console.log(max);

    The Spread operator has the same notation as the rest parameter which is 3 dots ... followed by the name of the array. In the example above, we passed the spread operator followed by the array name, so those array elements are passed as individual arguments to Math.max() function. This way we do not have to worry about the number of array elements and the spread operator also solved the problem we faced earlier, where we were getting Nan as result.

    You can do the same with multiple arrays using the spread operator,

    var array1 = [3, 5, -10];
    var array2 = [6, 2, -7, 3, 5];
    console.log(Math.max(...array1, ...array2));    // 6

    You can even combine the spread operator with other normal arguments,

    var array1 = [3, 5, -10];
    var array2 = [6, 2, -7, 3, 5];
    console.log(Math.max(3, ...array1, 10, ...array2, 11));    // 11

    In the code above we have passed two arrays as individual arguments using the spread operator along with one other normal argument to the function Math.max() to find the maximum out of all those passed arguments.

    Spread operator within arrays

    Apart from the uses above, if we want to create a new array using elements of another array or we want to include elements of another array into an existing array, we can do so using the spread operator.

    var fruits = ["apple", "mango", "pineapple"];
    var allFruits = ["grapes", ...fruits, "strawberry"];
    
    console.log(allFruits);    // ["grapes", "apple", "mango", "pineapple", "strawberry"]

    In the above example, we have an array fruits using which we created a new array allFruits, using the spread operator which placed all the elements of fruits array as individual elements within the new array.

    We can also use the spread operator to copy an array into another array.

    var arr1 = [1,2,3];
    var arr2 = [...arr1];
    arr2.push(4);
    console.log(arr2);   // [1, 2, 3, 4]
    console.log(arr1);   // [1, 2, 3]

    And we can event concatenate two different arrays to form a new array.

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


    Conclusion

    • Both the rest parameter and spread operator are represented with 3 dots ... followed by a variable name.
    • The rest parameter converts the rest of the arguments passed to a function into an array.
    • The Spread operator converts an array into individual array elements.

    Hope you understood the concept and do let us know if you have any suggestions or questions.

    Happy learning!

    Frequnetly Asked Questions(FAQs)

    1. What is the spread operator in JavaScript ES6?

    The Spread Operator in JavaScript( ... ) copies everything that an existing array or object contains and pastes it into another array or object.

    2. What is the difference between rest and spread operator in JavaScript?

    Feature Rest Operator Spread Operator
    Syntax Uses ... before a function parameter Uses ... before an array or object
    Usage Used to capture multiple function arguments into an array Used to spread elements of an array or object into separate arguments
    Functionality Gathers multiple arguments into an array within a function Expands elements of an array or object for use in another array or object
    Example function foo(...args) { // code } const arr = [1, 2, 3]; const newArr = [...arr];
    Use Case When the number of function arguments is not fixed or is unknown When you want to spread the elements of an array or object into another array or object
    Mutability Creates a new array or object within the function Does not modify the original array or object
    Compatibility Introduced in ES6 (ECMAScript 2015) Introduced in ES6 (ECMAScript 2015)

    3. How can I use the spread operator to combine arrays?

    To combine arrays using the spread operator, simply place the spread operator before each array that you want to merge. For example: [...array1, ...array2, ...array3] will create a new array that contains all elements from the individual arrays.

    4. Can I use the spread operator to clone an array or object?

    Yes, the spread operator is an excellent way to create a shallow copy of an array or object. By spreading the elements of the original array or object into a new array or object, you create an independent copy that can be modified without affecting the original.

    You may also like:

    About the author:
    I am software engineer by profession and an YouTuber by passion. I mostly blog or YouTube on Technology trends and more passionate towards JavaScript and JavaScript frameworks. Fond of anything related to Front End Development. A quick learner!
    Tags:JavaScript
    IF YOU LIKE IT, THEN SHARE IT
     

    RELATED POSTS