This functionality was officially added to JavaScript with the ES6 update, also known as ECMAScript 2015. But what does it do, and how can you benefit from using it in your education and daily work? In this tutorial, you’ll learn what a spread operator is, how to make the most of it, and in what situations.

Spread operator basics

The goal of the spread operator is to simplify work with existing arrays or objects in other arrays. Syntax-wise, a spread operator looks like this:

(...)

Three dots is a spread operator, which is most commonly used to spread out elements of an iterable object, including array, map, or set. Consider the following example that shows how a spread operator can be most easily used:

const arrValue = ['We', 'are', 'learning', 'JavaScript'];
console.log(arrValue);   // ["We", "are", "learning", "JavaScript"]
console.log(...arrValue); // We are learning JavaScript

In this example, the code console.log(...arrValue) is equivalent to a line with the sentence “We are learning JavaScript.” For a more nuanced use, consider this as the valid syntax of the JavaScript spread operator:

var variablename1 = [...value];

In this instance, serves as a spread operator, which targets all values in a specified variable. Because the use of the spread operator is not limited to a single case, let’s review the most common use cases, such as Expand, Concat, or Math, one by one.

It’s important to remember that spread cannot be the last parameter (for values), as this will turn it into a rest. At the same time, it will be correctly processed if it is the only one in the parameter list.

Incorrect:

function Test(a, ...spreadValues){}

Correct:

function Test(a, ...spreadValues, b){}
function Test(...spreadValues, a, b){}

The difference between Spread and Rest

The spread and rest operators are similar, so JS beginners often confuse them. Both operators are implemented in the same way in the code using the ellipsis (...), and both add new values to existing ones. Nevertheless, there are a few differences depending on the context:

1. Values. Spread increments the target array by the number of new values, while the rest adds them all as a single variable.

2. Position in the code. Spread can be mentioned at the beginning and in the middle of a list of elements. The rest operator is always written at the end of the list of function parameters.

3. Use. Spread can be used for arrays, object literals, and functions, while rest can only be used in functions.

How to use the spread operator

  • Adding a new element to array

Spread automatically expands an array, so it can be used as an alternative way to add a new value to an array.

let numbers = [1, 2];
console.log(numbers = [...numbers, 0, ...numbers, 0, ...numbers]);

Result:

[ 1, 2, 0, 1, 2, 0, 1, 2 ]
  • Combining arrays

Let’s review how to expand method benefits from the spread operator with the following code example:

// expand using a spread operator
let arr = ['1','2'];
let arr2 = [arr,'3','4'];

console.log(arr2); // [ '1', '2' , '3', '4' ]

If you run this code through a compiler, you’ll see the following range of numbers as an output: [ '1', '2', '3', '4' ]. What makes the application of a spread operator helpful is that you don’t get an array locked into another array. See how this example works if you omit using a spread operator:

// usually used expand method
let arr = ['1','2'];
let arr2 = [arr,'3','4'];

console.log(arr2); // [ [ '1', '2' ], '3', '4' ]

As you can see, without a spread, numbers 1 and 2 are locked in an array, which, in turn, is located in a larger array. Thus, using a spread operator helps omit such issues, which can be crucial for working with more numbers and value ranges.

  • Merging arrays

In a general setting, the concat() method is something you’d use for the concatenation of two or more strings. If you work with arrays, check out the following code that says enough:

// the usual array concat() method
let arr = [7,8,9];
let arr2 = [1,2];
arr = arr.concat(arr2);

console.log(arr); // [ 7, 8, 9, 1, 2 ]

The usual array concat() method can be simplified with the use of a spread operator, making a slight adjustment to the code, which will look like that:

// spread operator as a concat
let arr = [7,8,9];
let arr2 = [1,2];
arr = [...arr,...arr2];

console.log(arr); // [ 7, 8, 9, 1, 2 ]

While the console outputs are the same, unlike the expand option, a spread operator simplifies the input, especially when working with vast data arrays.

  • Arrays cloning

Because JavaScript uses references instead of values to assign objects, the change in variables using push() will change two variables instead of just one. With a spread operator, you can copy arrays so that they don’t refer to that one array. Let’s illustrate this trick with the following example:

let arr1 = [ 5, 6, 7];
// copy using spread syntax
let arr2 = [...arr1];
 
console.log(arr1); // [5, 6, 7]
console.log(arr2); // [5, 6, 7]

// append an item to the array
arr1.push(4);

console.log(arr1); // [5, 6, 7, 8]
console.log(arr2); // [5, 6, 7]

If you run this code through a console, you’ll see that two arrays are different because you pushed 8 into a second array. If you were not using a spread operator, these two arrays would be identical. In other words, 8 would be pushed to both arrays.

  • Adding values to Objects

As with arrays, the spread operator allows you to conveniently add new values to them.

let country1 = {city: 'Madrid'};
let countries = {...country1, country: 'Spain'};
console.log(countries);

Result:

{ city: 'Madrid', country: 'Spain' }
  • Objects combining

The spread operator can be used to combine the contents of objects separately and together with new values.

let numbers = {num: 0}
let symbols = {char: "A"}
let merged = {...numbers, ...symbols, word: 'Word'}

console.log (merged);

Result:

{ num: 0, char: 'A', word: 'Word' }
  • Objects cloning

If we use spread and a reference to an existing object in the declaration of a new Object, then we can clone its contents.

Warning: Only primitive values will be cloned, all properties storing objects will copy the reference to the memory area in which the original object is located. This means that by changing such a property in a new object, we mutate the original object.

let Obj1 = {num: 0, word: 'Word'};
let newObj = {...Obj1};

console.log(newObj);

Result:

{ num: 0, word: 'Word' }
  • Math object

As for the Math object, its use in JavaScript is exhaustive, but you can experiment with finding particular numbers from the list. In the usual use-case scenario, the Math object can find the minimum from a list of numbers. Check out the following code:

console.log(Math.min(8,9,10,4)); //4

In this case, the minimum number is obviously 4, but what if you have to use an array instead of a list?

// array using Math.min()
let arr = [8,9,10,4];

console.log(Math.min(arr)); //NaN

As you can see, your console will return you a NaN, which is not something you were expecting. For a proper application of the Math object with arrays, a spread operator will help significantly. Solve this issue using the following example:

// using a spread operator
let arr = [8, 9, 10, 4];

console.log(Math.min(...arr)); //4

As you can see, the spread operator helps utilize other JavaScript objects correctly, especially when working with arrays.

  • Extending construct

In Javascript, constructs are methods designed to work with Class objects (e.g. Date). Like other methods, they can take parameters, so spread can be used to work with them too if you keep required syntax and data types.

More use cases

Because a spread operator in JavaScript has comprehensive functionality, its uses are not limited to our indicated examples. When you learn more about allowing array elements to be passed as individual arguments or modifying the elements of one array and pushing them to another array.

  • So, let’s sum up what a spread operator can help you with. You can use this addition to JavaScript to:

  • Unpack elements of an iterable object, such as arrays, maps, and sets into a list.

  • Save time and add more options while working with Expand, Concat, and Math.

  • Clone an iterable object or merge a few objects into one.

  • Convert NodeList to an array.

  • Combine properties of a few objects into a different object, without significant conflicts between the two.

Test yourself

  • Task 1. Merge two arrays into the basket array, using the spread operator. Print the values of the new array to the console.

let fruits = [apricots, avocado, lemon];
let vegetables = [artichokes, asparagus, garlic];

Solution

let fruits = ['apricots', 'avocado', 'lemon'];
let vegetables = ['artichokes', 'asparagus', 'garlic'];
let basket = [...fruits, ...vegetables];
console.log(basket);

Result:

[ 'apricots',  'avocado',  'lemon',  'artichokes',  'asparagus',  'garlic' ]
  • Task 2. Create a new array that contains the names of all the months of the year using the spread operator and print the array values to the console. Add missing months manually.

let winter = [December, January, February];
let spring1 = [March];
let spring2 = [May];
let summer = [June, July]

Solution

let winter = ['December', 'January', 'February'];
let spring1 = ['March'];
let spring2 = ['May'];
let summer = ['June', 'July'];
let allSeasons = [...winter, ...spring1, 'April', ...summer, 'September', 'October', 'November'];

console.log(allSeasons);

Result:

[ 'December',  'January',  'February',  'March',  'April',  'June',  'July',  'September',  'October',  'November']
  • Task 3. Merge objects, then add to received Object literal quantity with value 2. Print the result to the console.

let obj1 = {type: 'Car'};
let obj2 = {colour: 'White'};

Solution

let obj1 = {type: 'Car'};
let obj2 = {colour: 'White'};
let obj3 = {...obj1, ...obj2, quantity:2 };

console.log(obj3);

Result:

{ type: 'Car', colour: 'White', quantity: 2 }