Dynamic parameters in JavaScript

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.

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

Leave a Reply

Your email address will not be published. Required fields are marked *