Post

JavaScript's three dots ( ... ): Spread vs rest operators

Draft updated on Invalid Date
Default avatar

By Joy Warugu

JavaScript's three dots ( ... ): Spread vs rest operators

This tutorial is out of date and no longer maintained.

Introduction

ECMA6 came out with some cool new features using three dots, or ellipsis, (...). 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 first 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, etc.

Arguments keyword

Before rest parameters existed, to get all the arguments in a function we used arguments which is an array-likeobject.

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' ].

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 can 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).

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 of the difference, I personally loved this illustration by Stephanie Nemeth. Make sure to follow her on Twitter for similar code facts illustrations.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Joy Warugu

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel