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.
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 argument
s 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: