Many programming languages have this. Instead of defining all parameters for a function, you can pass any number of parameters into a function and then work with them.
Functions with static parameters
Before we get into dynamic parameters, let us introduce a function we can then work on. How about one adding two numbers?
function sum( a, b ) {
return a + b;
}
console.log( sum( 4, 5 ) ); // 9
Nothing special here, right? But what would happen if we just add more parameters to the function call?
console.log( sum( 4, 5, 6 ) ); // 9
Nothing would happen, since the function is only using the first two parameters. But you not get an error. JavaScript is simply not using the third parameter.
The arguments object
Even if we don’t use the third parameter, it is still available. But how can we use it, when we don’t have a parameter name for it? We can use the arguments
object to get all the parameters, even if we haven’t even defined any parameter for the function:
function sum() {
let total = 0;
for (const number of arguments) {
total += number;
}
return total;
}
console.log( sum( 4, 5 ) ); // 9
console.log( sum( 4, 5, 6 ) ); // 15
The arguments
object works very much like an array. You can access the first parameter with arguments[0]
, etc. In our sum()
function, we don’t even have any arguments at all, as mentioned before. But you can also combine defined and additional ones:
function someFunction( a, b ) {
console.log( a ); // 4
console.log( b ); // 5
console.log( arguments ); // [4, 5, 'a string', Array(2), ...]
}
someFunction( 4, 5, 'a string', [ 'an', 'array' ] );
The arguments
object always contains all parameters passed to the function, even those with a name. The object has some other properties, you can read more about in the documentation.
The rest parameter
A more modern way to use dynamic parameters in JavaScript is the rest parameter. Let’s start with a simple example again. We implement our sum()
function and use the rest parameter this time:
function sum( ...numbers ) {
let total = 0;
for ( const number of numbers ) {
total += number;
}
return total;
}
console.log( sum( 4, 5 ) ); // 9
console.log( sum( 4, 5, 6 ) ); // 15
The only parameter here is “...numbers
“, and this is the “rest parameter”. Another good example is this one:
function calc( operation, ...numbers ) {
switch ( operation ) {
case "sum":
return numbers.reduce( ( total, num ) => total + num, 0 );
case "multiply":
return numbers.reduce( ( product, num ) => product * num, 1 );
case "subtract":
return numbers.reduce( ( difference, num ) => difference - num );
case "divide":
return numbers.reduce( ( quotient, num ) => quotient / num );
default:
console.error(`Invalid operation "${operation}"`);
return;
}
}
console.log( calc( "sum", 4, 5, 6 ) ); // 15
console.log( calc( "multiply", 4, 5, 6 ) ); // 120
Now the “rest” makes sense, right? We have some normal parameters, followed by the rest parameter, which contains all other parameter, or simply, the rest of the parameters. You can always only have one rest parameter, and it must be the last parameter. This example also shows a good use case for the console.error()
function from our previous blog post.
Bonus: the arguments object used as the rest parameter
In our first example on the rest parameter, you wouldn’t even need to have the ...numbers
parameter, since it’s the only parameter. You could just have used argument
object in combination with the spread operator like this:
function sum() {
let total = 0;
const numbers = [...arguments]; // Convert arguments object to a real array
for (const number of numbers) {
total += number;
}
return total;
}
This conversion in line 3 is not really necessary, since the arguments
object behaves very similar to an array, but nonetheless you can do it and might have a use case for this. But as soon as you have more (named) parameters, that probably wouldn’t work anymore.
Conclusion
A function with a fixed number of arguments might be too inflexible, especially, when you deal with arrays or lists. In these cases, the rest parameter or the arguments
object can help to write some nice and short functions.