CLOSE

   JavaScript  Rest Parameter  Spread Operator  
   Technology    Programming

Rest Parameter and Spread Operator in JavaScript ES6

           
 JANUARY 10, 2019   by Belide91

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 which 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 Operators can prove very helpful in javascript 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.




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 argument 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 maximum out of 3 numbers once and then the next time we have to find maximum out of 4 numbers, or out of 5 numbers. To accomodate 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 theay 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 arguments 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 on using index, like we have done in the example above.




Rest Parameters

In the section above, we have seen how arguments 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 Rest parameter.

Rest parameters allow you to pass arguments as an array to a function. You must be wondering that the arguments variable was doing the same thing, but in case of arguments variable the values are stored just like 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 case of Rest parameters, values are actually gatthered 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 Parameters

Let us take a simple example to find 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 Rest Parameters

Now, let us see how above mentioned function for finding out 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(variable name which is an array), hence it is also called as named parameter. In the above example, numbers is preceded with a 3 dots ... which is a rest parameter.

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 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.


Rest parameter must be at the end

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

If you pass a few arguments to any function including rest parameter, then 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 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;
}



Spread Operator

We have seen rest parameter converting individual arguments passed to a function into an array, in this section we will learn about spread operator. Spread operator does the exact opposite to what 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 as result.

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

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 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);

Spread operator has the same notation as rest parameter which is 3 dots ... followed by the name of the array. In the example above, we passed spread operator followed by the array name, so that 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 spread operator also solved the problem which 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 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 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 for 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 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 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 rest parameter and spread operator are represented with 3 dots ... followed by a variable name.
  • Rest parameter converts rest of the arguments passed to a function into an array.
  • 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!


SHARE YOUR THOUGHTS WITH US!




       

Made with by Abhishek Ahlawat

© 2019 Studytonight.   All rights reserved.

DMCA.com Protection Status