This operator is known as “spread” or “rest”. It is 3 dots.

...

Basic

On the right side of assignment, it is a spread operator.

const x = [8, 9]
const y = [4, 5, 6, ...x]

On the left side of assignment, it is a rest operator. You get three variables here - a, b and other.

const [a, b, ...other] = [1, 2, 3, 4, 5]

On a key-value pairs object

const x = {a: 1, b: 2}

const y = {
  ...x,
  c:3
}

y
// { a: 1, b: 2, c: 3}

On an array

Unpack

Here using the spread operator in the variable names on the left.

We unpack an array into multiple variables. The last variable is always an array while the others are scalar items.

Notes

  • Spread must be for the last variable only or you’ll get an error. This is invalid: const [...a, b ] = myArray.
  • You must use hard brackets or the syntax is invalid.
  • You can leave out the const bit, like if using the interactive console.

Two variables

Here we unpack multiple items into a flat array.

const myArray = ["abc", "def", "efg"]

const [a, ...b] = myArray
a
// 'abc'
b
// [ 'def', 'efg' ]

// With the variables already assigned as split values, you can combine them again.
[a, ...b]
// [ 'abc', 'def', 'efg' ]

Three variables

const myArray = ["abc", "def", "efg"]

const [a, b, ...c] = myArray
> a
'abc'
> b
'def'
> c
[ 'efg' ]

If you don’t care about the other values of the aray.

Here dropping the third element.

const [a, b, ..._] = x

// Or simply
const [a, b] = x

Single variable

You could use a single variable. But you probably shouldn’t.

const [...a] = x
a
// [ 'abc', 'def', 'efg' ]

That makes a as an independent copy of x.

Here is the preferred way to copy an array - see the Clone section.

const a = [...x]

Merge

Here using the spread operator in the values on the right.

Use spread to unpack an array into its elements, such as for merging arrays into a single, flat (one-dimensional) array.

const x = [ "a", "b", "c" ]
const y = [ "d", "e", "f" ]
const z = [...x, ...y, "g"]
z
// [ "a", "b", "c",  "d", "e", "f", "g" ]

Compare without using spread. You get a nested array.

const z = [x, y, "g"]
z
// [
//   [ "a", "b", "c" ],
//   [ "d", "e", "f" ],
//   "g"
// ]

Clone

Make a copy of an array, but one that is independent of the original one.

const x = [ "a", "b", "c" ]

const y = [...x]

// Update x only, without affecting y.
x.push("d")

x
// [ "a", "b", "c", "d" ]
y
// [ "a", "b", "c" ]

Compare with just a reference, where both variables point to the same array in memory.

const x = [ "a", "b", "c" ]
const y = x

x.push("d")

x
// [ "a", "b", "c", "d" ]
y
// [ "a", "b", "c", "d" ]

On an iterable

Convert an iterable which is not an array into an array, so you can use array methods on it.

For example, a selection of DOM elements.

// Iterable.
const divs = document.getElementsByTagName('div')

// Array.
const divsArr = [...divs]
// Array method.
divsArray.map(myFunc)

Function

This is convenient as you can one or more values without having to make an array.

function sum(...values) {
    let total = 0;
    for (const a of values) {
        total += a;
    }
    return total;
}

sum(1);       // 1
sum(1, 2, 3); // 6

// In case you do have a array, you can spread the single array into arguments.
const items = [1, 2, 3];
sum(..items); // 6

Compared with a plain approach before ES6.

function sum(values) {
    let total = 0;
    for (const a of values) {
        total += a;
    }
    return total;
}

sum([1]);       // 6
sum([1, 2, 3]); // 6