Spreading…with the JavaScript spread operator

Reading Time: 3 minutes 🕑

Last updated: October 18, 2021.

If you can loop over something in JavaScript, you can apply the spread operator (...) to it.

The operator will take all items it loops through and spread them in array format.

Spread operator basics

Here’s the basic syntax:

// Two things we can iterate through
const beers = ["Hoppy", "Fruity", "Ale"]; // An array
const wines = ["Spanish red", "Italian white", "Colombian special"]; // Another array

// Combine both into new array
const menu = [...beers, ...wines];

console.log(menu); // [object Array] (6) ["Hoppy","Fruity","Ale","Spanish red","Italian white","Colombian special"]

Before the introduction of the spread operator in ES6 (2015), we could have achieved the same result this way:

const beers = ["Hoppy", "Fruity", "Ale"]; // Array 1
const wines = ["Spanish red", "Italian white", "Colombian special"]; // Array 2

const menu = beers.concat(wines);

console.log(menu); // [object Array] (6) ["Hoppy","Fruity","Ale","Spanish red","Italian white","Colombian special"]

The spread operator is slightly easier to read. This becomes even more so if the operation is more complex. Let’s say I want to add one more beer to the beers array and one more wine to the wine array.

With pre-ES6 syntax, we could achieve this using concat:

const menu = beers.concat("IPA").concat(wines).concat("French red");

console.log(menu); // // [object Array] (8) ["Hoppy","Fruity","Ale","IPA","Spanish red","Italian white","Colombian special","French red"]

It works, but it is already become hard to read.

Using the spread operator provides a much more readable solution

const menu = [...beers, "IPA", ...wines, "French red"];

console.log(menu); // [object Array] (8) ["Hoppy","Fruity","Ale","IPA","Spanish red","Italian white","Colombian special","French red"]

This is nice and easy to read, even if it became more complex.

But its use cases don’t stop there.

Key use cases

#1 Passing data into a function with the spread operator

The spread operator provides a clean solution to feed individual items into a function.

In the below example, the code shows how we could do this without the spread operator:

// Data to feed in
let data = ["James","80"]

// Define function
function showScore(name, score) {
console.log(`Great job ${name}! You scored  points.`)
}

// Call function (without spread operator)
showScore(data[0], data[1]); // "Great job James! You scored 80 points."

But we could also pass in the data using the spread operator:

// Using spread
showScore(...data); // "Great job James! You scored 80 points."

#2 Creating a function with an unspecified number of arguments

Sometimes we may not know how many arguments we want to pass into a function.

For example, we may want to create a reusable function to print a full name that takes in an array. But we don’t know how many elements (names) will be in that array.

In this case, we can use the spread operator when defining the parameters of the function. It will then accept as many arguments (names) as we input when calling the function:

printFullName("Jose","Fernandez","Perez","Felix"); // "Jose Fernandez Perez Felix"

function printFullName (...args) {
  const fullName = args.join(' ');
  console.log(fullName);
}

So we can use the spread operator as a way to enable flexibility in data input for functions.

#3 Convert strings to individual array elements

We can also use the spread operator to make each character in a string its own individual array item:

const name = "James";

nameArray = [...name];

console.log(nameArray); // [object Array] (5) ["J","a","m","e","s"]

#4 To feed in an array of numbers to the Math() object

Below, the spread operator feeds in all the elements of the numbers variable for the Math() object to do its magic:

const numbers = [1, 2, 3];

const min = Math.min(...numbers);
const max = Math.max(...numbers);

console.log(min); // 1
console.log(max); // 3

#5 Last (but definitely not least), copying an array

Making a copy of an array for further editing in JavaScript can be surprisingly problematic:

const beers= ["Hoppy", "Fruity", "Ale"];

const beersComplete = beers;

beersComplete.push("IPA");

console.log(beersComplete); // [object Array] (4) ["Hoppy","Fruity","Ale","IPA"]
console.log(beers); // [object Array] (4) ["Hoppy","Fruity","Ale","IPA"]

We have edited the ‘new’ array. But in doing so, we have also changed the original array.

This is because we didn’t really make a new array as a copy. In this situation, the JavaScript engine makes beersComplete a reference of beers. Because of this, when we edit beersComplete, we are editing the original array.

If we want to make a copy that isn’t just a reference, we can use the spread operator:

const beers= ["Hoppy", "Fruity", "Ale"];

const beersComplete = [...beers];

beersComplete.push("IPA");

console.log(beersComplete); // [object Array] (4) ["Hoppy","Fruity","Ale","IPA"]
console.log(beers); // [object Array] (4) ["Hoppy","Fruity","Ale"]

Now, we are spreading the contents of beers into a new array saved as beersComplete. So this is now a copy of the contents of the beers array in a totally new array called beerComplete.