What do the three dots (…) mean in JavaScript?

Adrian Oprea
3 min readAug 27, 2018

--

By Otter GFDL or CC-BY-SA-3.0, from Wikimedia Commons

Originally published at https://oprea.rocks/blog/what-do-the-three-dots-mean-in-javascript/

The title of the article is from a question I was asked to answer on Quora. Below, is my attempt to explain what do the three dots do in JavaScript. Hopefully, this removes the fog around the concept, for people who will find this article in the future and have the same question.

Array/Object spread operator

Assume you have the following object:

const adrian = {    fullName: 'Adrian Oprea',    occupation: 'Software developer',    age: 31,    website: 'https://oprea.rocks'};

Let’s assume you want to create a new object(person) with a different name and website, but the same occupation and age.

You could do this by specifying only the properties you want and use the spread operator for the rest, like below:

const bill = {    ...adrian,    fullName: 'Bill Gates',    website: 'https://microsoft.com'};

What the code above does, is to spread over the adrian object and get all its properties, then overwrite the existing properties with the ones we're passing. Think of this spread thing as extracting all the individual properties one by one and transferring them to the new object.

In this case, since we specified the fullName and website properties after the spread operator kicked in, the JavaScript engine is smart enough to know that we want to overwrite the original values of those properties that are coming from the original object.

It’s a similar situation with arrays. Except that instead of spreading over keys and values, the operator spreads indexes and values. Unlike object spread, where you won’t have duplicate properties because that’s just how JavaScript objects work (you can’t have an object with two fullName properties), with arrays you may end up with duplicate values, if you plan to implement something similar to our object example.

This means that the code below will result in you having an array with duplicate elements.

const numbers1 = [1, 2, 3, 4, 5];const numbers2 = [ ...numbers1, 1, 2, 6,7,8]; // this will be [1, 2, 3, 4, 5, 1, 2, 6, 7, 8]

Think of it as a replacement for Array.prototype.concat.

Rest operator

When used within the signature of a function, where the function’s arguments should be, either replacing the arguments completely or alongside the function’s arguments, the three dots are also called the rest operator.

When it is used like that, the rest operator enables the developer to create functions that can take an indefinite number of arguments, also called functions of variable arity or variadic functions.

Here’s the simplest example of such a function. Let’s assume you want to create a function that calculates the sum of all its arguments. Note that it’s not the sum of two, three or four numbers but the sum of all the numbers the function would receive as arguments.

Here is a naive implementation, using the rest operator

function sum(...numbers) {    return numbers.reduce((accumulator, current) => {        return accumulator += current    });};sum(1, 2) // 3sum(1, 2, 3, 4, 5) // 15

The simplest explanation would be that the rest operator takes the arguments that a function receives and dumps them into a real array that you could later use.

You might argue that you can do this by requesting the user to pass an array of numbers. That’s technically doable but poor UX for your API, since users expect to call a sum function with plain numbers, not a list of numbers.

You might also argue that you could use the arguments array. That’s also true but be careful, arguments is not a real array but an array-like object(an object with a length property). It actually looks like this, for the first call of our sum function, in the previous example:

{    '0': 1,    '1': 2,    'length': 2}

To manipulate this object and use array methods on it such as reduce, from my previous example, you’d have to do the Array.prototype.slice.call(arguments, 0) thing. That doesn’t perform well, in terms of speed and memory usage and is not elegant. It’s just smartass code that’s prone to confuse your junior colleagues.

This should be everything you need to know to be productive with the rest/spread operator in JavaScript.

If you have any advice on how to improve the article, or you need some help wrapping your head around the concept, leave a comment, below.

Keep an open mind!

Adrian.

--

--