JavaScript Rest Parameter Simplified

A deep dive into the rest parameter — understanding why and how to use them.

Avinash Nandan
JavaScript in Plain English

--

Photo by Sincerely Media on Unsplash

ES6 has brought in several features which have made life simpler for JavaScript developers. One of the features among them is the rest parameter. Today, in this article we dive into rest parameters and try to understand how to use them and why to use them.

So, let’s start.

What is Rest Parameter?

As the name suggests, rest parameters are used to access the arguments passed into the function and do any operations on the passed arguments.

Prior to using the rest parameter, developers used to use arguments object for the same. Let’s see what is this arguments object and why it is better to use the rest parameter instead of the arguments object.

Take a look at the below snippet for the same:

function argumentExample(a, b) {console.log('Value of A', a);console.log('Value of B', b);console.log('Value of C', arguments);}argumentExample(1, 2, 3, 4);Value of A 1
Value of B 2
Value of C [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }

So, as you can see arguments variable holds all the arguments passed into the function. Now, the question may arise, if we have this arguments object already available then what is the purpose of using the rest parameter.

So, here are some cons of the arguments object:

  1. arguments object holds all the arguments passed (one which is assigned to the variable and the left one too). So, if there is a need to get the information about the rest of the parameters then we have to do extra computation.
  2. arguments object does not have access to array methods/properties by default. So, if we have to perform any operation on arguments iteratively then they will fail.
function argumentExample(a, b) {console.log('Value of A', a);console.log('Value of B', b);console.log('Value of C', typeof arguments);arguments.map((elem) => {console.log(elem);});}argumentExample(1, 2, 3, 4);

Herein, if we try to use the map operator with arguments, we will get an error as shown below:

TypeError: arguments.map is not a function
at argumentExample (D:\Blog_Topic\Destructure\rest.js:13:13)
at Object.<anonymous> (D:\Blog_Topic\Destructure\rest.js:18:1)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
at node:internal/main/run_main_module:17:47

The only solution left is to convert arguments to an array first.

3. arguments object does not work well in the arrow function.

const argumentExample = (a, b) => {console.log('Value of A', a);console.log('Value of B', b);console.log('Value of C', arguments);};argumentExample(1, 2, 3, 4);Value of A 1
Value of B 2
Value of C [Arguments] {
'0': {},
'1': [Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: Module {
id: '.', .....

In the above snippet, the value of arguments object is some weird value.

Basically, arrow functions do not have an arguments object of their own. They have access to the arguments object of the closest non-arrow parent function and so the same value is printed out here.

In order to avoid the cons mentioned above, it is better to switch to rest parameters. Let’s look into it in detail.

Basic usage

function restExample(a, b, ...c) {   
console.log('Value of A', a);
console.log('Value of B', b);
console.log('Value of C', c);
}
restExample(1, 2, 3, 4);
// Output
Value of A 1
Value of B 2
Value of C [ 3, 4 ]

In the function definition, we have defined function parameters as (a, b, …c). Here (…c) is the way we define the rest parameter i.e. three dots followed by the variable name. Behind the scenes, JavaScript assigns parameters to the arguments passed in the function on one to one basis and as soon as it comes across the rest parameter, it assigns all the rest of the parameters to the variable defined with the variable name.

The important thing to note here is rest parameter has access to array properties and methods, so the same can be leveraged to do any computation. Let’s see a snippet for the same:

function restExample(a, b, ...c) {console.log('Value of A', a);console.log('Value of B', b);c.map((elem) => {console.log('Elem', elem);});}restExample(1, 2, 3, 4);Value of A 1
Value of B 2
Elem 3
Elem 4

Some gotcha’s while using rest parameter

The rest parameter should be your last parameter:

function restExample(a, ...c, b) {console.log('Value of A', a);console.log('Value of B', b);c.map((elem) => {console.log('Elem', elem);});}restExample(1, 2, 3, 4);function restExample(a, ...c, b) {
^
SyntaxError: Rest parameter must be last formal parameter

If we try to use the rest parameter in between, we will encounter an error explaining that it should be the last parameter.

There has to be a single rest parameter in a function:

function restExample(...a, ...c) {console.log('Value of A', a);console.log('Value of B', c);}restExample(1, 2, 3, 4);function restExample(...a, ...c) {
^
SyntaxError: Rest parameter must be last formal parameter

In the above example, we tried using 2 rest parameters, but in that case too we received an error.

So, this in nutshell is all about the rest parameter. Hope you are able to understand it in a better way now. If you have any queries or concerns do let me know in your response.

About me — I am a programming enthusiast who likes to read and write about Frontend Designs, JavaScript, and UI/UX-related stuff. Click here to read all my articles and do let me know your feedback.

More content at PlainEnglish.io. Sign up for our free weekly newsletter. Follow us on Twitter and LinkedIn. Check out our Community Discord and join our Talent Collective.

--

--

Engineer, Tech Blogger, Programmer, Movie Buff, Sports Lover. I like to read about tech and write about it and connect with like minded people.