Before looking into Rest Parameters And Spread Operator, it is important to understand what Default parameters are.
Default Parameters
Default parameters allow you to give a default value to a parameter in a function.
In the code block below, name is a default parameter and it contains a single line of statement.
The name variable when initialized with the value World, and the sayHi function invoked, the result, Hello World is printed to the console.
But if sayHi is invoked with an argument like John, we have Hello John.
In the second block, we have the same function as the first, but it takes an additional parameter message without any default value.
Invoking the function, sayHi, with only the argument, Hello, outputs Hello World to the console, since the second parameter name, has default value World.
However, if the sayHi function is invoked again with two arguments, Hi and John, the output is Hi John.
function sayHi(name = "World") {
console.log("Hello " + name);
}
sayHi();// Hello World
sayHi("John");// Hello John
function sayHi(message, name = "World") {
console.log(message + name);
}
sayHi("Hello");// Hello World
sayHi("Hi", "John");// Hi John
If one argument is passed, when calling the sayHi function, it represents the first function parameter (non-default parameter), but if it is two arguments, it represents both, in the order it is passed.
Note:
Please note that the default parameter in our function definition should always come after the regular parameters.
So in our sayHi function here, message cannot come after the name parameter, otherwise we get undefined, and message never gets initialized;
Rest Parameters
With rest parameters, you can define a function to store multiple arguments in a single array. This is especially useful when you're invoking a function with multiple arguments.
In the example below, we define a greet function with the names parameter. The dot, dot, dot (...) is what makes names a rest parameter and allows greet to accept multiple arguments.
We then use the forEach method to iterate over each name value and print the string Hi, followed by the each name from the array of argument.
let sayHi = function greet(...names) {
names.forEach(name => console.log("Hi " + name));
}
greet("Mary", "John", "James");
// Hi Mary
// Hi John
// Hi James
Rest Parameters With Additional Parameter
Consider the same greet function, but with an additional parameter message.
let sayHi = function greet(message, ...names) {
console.log(message + "everyone!");
names.forEach(name => console.log("Hi " + name));
}
greet("Welcome", "Mary", "John", "James");
// Welcome everyone!
// Hi Mary
// Hi John
// Hi James
In the code block above, the greet function was declared with two parameters, message, and a rest parameter, name. And we call the function with four arguments passed.
The value Welcome gets assigned to the message parameter, while the rest of the arguments get stored as an array in the names parameter. The output in the console is as seen above.
If the message parameter is placed after names, we get syntax error stating that rest parameter must be the last formal parameter.
That's expected, as we want the rest of the arguments to be stored in a rest parameter and not a regular parameter.
Note:
Rest parameters provide a great deal of flexibility, but when mixed with regular parameters, should be placed last.
Spread Operator
Spread Operator allows a function to take an array as an argument and then spread out its elements so that they can be assigned to individual parameters.
Here we have a function greet with 2 parameters, person1 and person2. We invoke the function, but instead of passing in two arguments, we pass a single argument, i.e. an array using the spread operator. This then spread the values John and Mary (as the argument) for person1 and person2 respectively.
function greet(person1, person2) {
console.log("Hello " + person1 + " and " + person2);
}
let names = ["John", "Mary"];
greet(...names);// Hello John and Mary
In the example below, since string is an array of characters, each of the characters in the variable letters is spread out to the parameters of the display function, so the spread operator can be used with any iterable like string, array, or list.
function display(char1, char2, char3, char4) {
console.log(char1, char2, char3, char4);
}
let letters = "abcd";
display(...letters);// a b c d
If we initialize letters with more than four letters and then run the display function, the additional letters never get collected since we only have four parameters.
function display(char1, char2, char3, char4) {
console.log(char1, char2, char3, char4);
}
let moreLetters = "abcdefg";
display(...moreLetters);// a b c d
However, if we add a rest parameter called others to the display function, first the arguments a b c d gets assigned based on the parameters in the display function, then the other additional letters get stored in the rest parameter (as an array).
function display(char1, char2, char3, char4, ...others) {
console.log(others);
console.log(char1, char2, char3, char4);
}
let letters = "abcdefg";
display(...letters);// (3) ["e", "f", "g"]
// a b c d
Summary:
While the rest parameter collects individual arguments and stores them in an array, the spread operator takes an array as argument and spreads it into individual parameters.