Javascript’s ECMA6 came out with some cool new features; ...
is one of these new Javascript functionalities. It can be used in two different ways; as a spread operator
OR as a rest parameter
.
Rest parameter: collects all remaining elements into an array.
Spread operator: allows iterables( arrays / objects / strings ) to be expanded into single arguments/elements.
In this article we will look into these two ways of using ...
; keeping it short and sweet as usual. Enjoy!
Rest parameters
From the definition we saw earlier, rest parameters
collect all the remaining elements into an array. This allows us to do really neat function definitions. Let’s see how we put them to use.
function add(x, y) {
return x + y;
}
add(1, 2, 3, 4, 5) // returns 3
The above function call returns 3
, this is because in Javascript it is possible to call a function with any number of arguments. However, only the fist two arguments will be counted.
With rest parameters
we can gather any number of arguments into an array and do what we want with them. So we can re-write the add
function like this:
function add(...args) {
let result = 0;
for (let arg of args) result += arg;
return result
}
add(1) // returns 1
add(1,2) // returns 3
add(1, 2, 3, 4, 5) // returns 15
Note: Rest parameters have to be at the last argument. This is because it collects all remaining
/ excess
arguments into an array. So having a function definition like this does not make sense and it errors out. :
function abc(a, ...b, c) {
...
return;
}
We can separately define the first arguments, and the rest of the arguments in the function call (no matter how many they are) will be collected into an array by the rest parameter
.
function xyz(x, y, ...z) {
console.log(x, ' ', y); // hey hello
console.log(z); // ["wassup", "goodmorning", "hi", "howdy"]
console.log(z[0]); // wassup
console.log(z.length); // 4
}
xyz("hey", "hello", "wassup", "goodmorning", "hi", "howdy")
Since the rest parameter
gives us an array, we can use array methods like Array.find
e.t.c.
Arguments keyword
Before rest parameters
existed, to get all the arguments in a function we used arguments
which is an array-like
object.
function someFunction() {
return arguments;
}
someFunction("joykare", 100, false);
someFunction
returns the arguments and their indexes, [Arguments] { '0': 'joykare', '1': 100, '2': false }
.
The downside of using the arguments
keyword is that, it returns an array-like object; this means you essentially cannot perform any array-methods like; Array.filer, Array.map
. Another pitfall, is that we cannot use arguments
in arrow functions. This is because arrow-functions do not have their own this
, and hence no arguments
object either.
Spread operators
The spread operator
allows us to expand elements. With rest parameters
we were able to get a list of arguments into an array. spread operators
however, let us unpack elements in an array to single/individual arguments.
Some scenarios where this capability is useful include:
Adding array elements to an existing array
const arr = ["Joy", "Wangari", "Warugu"];
const newArr = ["joykare", ...arr];
The value of newArr
will be [ 'joykare', 'Joy', 'Wangari', 'Warugu' ]
. Note: Unlike rest parameters
you can use the spread operator
as the first argument. So if you wanted to add an element as the last element in your array you cna do this:
const myNames = [...arr, "joykare"];
The value of names
in this case will be [ 'Joy', 'Wangari', 'Warugu', 'joykare' ]
.
Copying arrays
We can use the spread operator
to copy an array.
const arr = [1, 2, 3];
const arr2 = [...arr];
This copies arr
into arr2
. Now we can do things on arr2
and any changes done to arr2
will not have any effect arr
.
Pass elements of an array to a function as separate arguments
If we had an array that we wanted to pass as a list of arguments in a function, we would use the spread operator
. Let’s reuse our add
function.
function add(a, b, c) {
return a + b + c ;
}
const args = [1, 2, 3];
add(...args);
The add
function call is similar to doing this: add(1, 2, 3)
.
Note: We have been using arrays to demonstrate the spread operator
, but any iterable also works. So, if we had a string const str = 'joykare'
, [...str]
translates to [ 'j', 'o', 'y', 'k', 'a', 'r', 'e' ]
.
Conclusion
...
could be used to represent either a spread operator
or a rest parameter
. How do we tell the difference? Well it entirely depends on how we use it. Given the context in which we use the three dots, it is easy to tell whether we are using it as a rest parameter
or a spread operator
.
I hope this article makes these two concepts clearer. For a very simplified explanation on the difference, I personally loved this illustration by Stephanie Nemeth. Make sure to follow her on twitter for similar code facts illustrations.
Source: Scotch.io