Rest Parameters, Spread Operator and Default parameters for Functions
Older Article
This article was published 9 years ago. Some information may be outdated or no longer applicable.
Here we’ll look at some great additions to functions in JavaScript that arrived with ES2015.
Rest Parameters
When working with functions, we often don’t know how many parameters will come in. A typical scenario: a function that lets users modify their profile. The user might change their profile picture, their date of birth, or something else entirely.
Preparing for every possibility is painful from a code perspective. Let’s look at an example. Say we want a function that adds up all the numbers passed to it. In older JavaScript, we’d write something like this:
function add() {
return Array.prototype.slice.call(arguments).reduce(function (acc, number) {
return acc + number;
});
}
console.log(add(3, 4, 6));
This works, but calling Array.prototype.slice.call(arguments) is ugly. The reason it’s so convoluted: arguments isn’t a real array, so it doesn’t have a .slice() method. We need to call Array.prototype.slice to use slice on arguments, and by calling .call() we tell the code it’s working on an array-like object. That was a mouthful.
In ES2015, we don’t need to worry about any of that. Applying rest parameters (plus arrow functions) to this example strips the code right down:
function add(...numbers) {
return numbers.reduce((acc, number) => acc + number);
}
console.log(add(3, 4, 6));
The syntax for rest parameters is three dots followed by an argument name. And ...numbers here is an actual Array instance, so we can call all array methods on it directly.
Spread Operator
There are other great uses for the spread operator (the three-dot syntax). Copying or combining arrays becomes trivially easy:
const fruit = ['apple', 'pear'];
const moreFruit = ['peach'];
const allFruit = [...fruit, ...moreFruit];
console.log(allFruit); // [ 'apple', 'pear', 'peach']
Default parameters
While we’re talking about function parameters, let’s cover default parameters (sometimes called the “default operator”).
This feature lets us set default values for function parameters. Here’s a function in older JavaScript that takes a number and multiplies it by another number (the second argument). If the multiplier isn’t passed in, we assume 1. If no number is provided, we assume 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));
Simple enough here, but imagine checking 10 arguments. A small function would balloon fast.
With ES2015, we can specify default values right in the parameter list:
function multiply(num = 0, multiplier = 1) {
return num * multiplier;
}
console.log(multiply(), multiply(5), multiply(5, 2));
Much cleaner. The same concept applies to the profile-update example from earlier. We can set default parameters for the function and only update the values that actually change.