Rest Parameters, Spread Operator and Default parameters for Functions

This post is 4 years old. (Or older!) Code samples may not work, screenshots may be missing and links could be broken. Although some of the content may be relevant please take it with a pinch of salt.

In this article we are going to be talking a bit more about Functions in JavaScript - namely, we'll see some great additions that became part of JavaScript via ES2015.

Rest Parameters

Often times when working with functions we are not sure how many parameters the function will receive. This would be the typical scenario for a function that allows us to modify a profile for a user – the user of our site may change profile picture, his date of birth or some other information.

Preparing for all possibilities is really a painful exercise from the code's perspective. Let's take a look at a few examples. Let's assume that we want to create a function that adds all parameters passed in to the function (assuming that these parameters are all numbers). In older versions of JavaScript we'd write something similar to this:

function add() {
return Array.prototype.slice.call(arguments).reduce(function (acc, number) {
return acc + number;
});
}

console.log(add(3, 4, 6));

This will of course work but calling Array.prototype.slice.call(arguments) is really not pretty. The reason why this works in such a complicated manner is because arguments isn't a real array, therefore it doesn't have a .slice() method (an actual array would have this method) so we need to call Array.prototype.slice which allows us to use the slice method on arguments and by calling .call() we tell our code that it's working on an array-like object and therefore it'll apply slice on it. Phew, that was quite complex, right?

Luckily in ES2015 we don't need to worry about this anymore – applying the Rest parameters (as well as the arrow functions) on this example will significantly reduce the amount of code (and explanation) that we need to take a look at:

function add(...numbers) {
return numbers.reduce((acc, number) => acc + number);
}

console.log(add(3, 4, 6));

The first thing to notice is the syntax for Rest Parameters – it's prefixed with three dots, followed by an argument name. And in this case ...numbers is an instance of an Array therefore we can use all the array methods on it directly.

Spread Operator

There are some other great use-cases for the spread operator (that's the syntax prefixed with three dots). Things like copying or combining arrays is now a really easy procedure:

const fruit = ['apple', 'pear'];
const moreFruit = ['peach'];
const allFruit = [...fruit, ...moreFruit];
console.log(allFruit); // [ 'apple', 'pear', 'peach']

Default parameters

While we are discussing parameters to a function, let's also discuss default parameters or sometimes called the 'default operator'.

This features essentially allows us to add default values to our function parameters. Let's create a function first using the older version of JavaScript that takes a number and multiplies it with another number (which is the second argument to the function). If the multiplier is not passed in, we should assume a value of 1, and if no number is used we should assume a value of 0:

function multiply(num, multiplier) {
num = num !== undefined ? num : 0;
multiplier = multiplier !== undefined ? multiplier : 1;
return num * multiplier;
}

console.log(multiply(), multiply(5), multiply(5, 2));

This is a simple example but imagine if we had to check for 10 arguments, a simple function would get very complex very quickly.

Using ES2015 we can simplify our code and specify the default parameters when specifying the parameters for our function:

function multiply(num = 0, multiplier = 1) {
return num * multiplier;
}

console.log(multiply(), multiply(5), multiply(5, 2));

This looks a lot cleaner now. We can apply the same concept to the example that I brought up at the beginning of this section – having a function that allows users to update their profiles. We can specify the default parameters for the function and if any of these parameters change we can update that value only.