JAVASCRIPT

JavaScript Spread Operator: Syntax, Usage, and Examples

The spread operator (...) lets you expand arrays, objects, or strings into individual values. You’ll use it a lot when copying data, merging values, or passing items into functions.

How to Use the Spread Operator

The spread operator looks the same everywhere, three dots: ...value. What changes is the context around it.

Spread in arrays

Use spread to expand an array into another array.

const snacks = ["chips","popcorn"];
const moreSnacks = ["nuts", ...snacks,"cookies"];

console.log(moreSnacks);
// ["nuts", "chips", "popcorn", "cookies"]

You can also use it to copy an array:

const scores = [10,20,30];
const scoresCopy = [...scores];

console.log(scoresCopy);
// [10, 20, 30]

Spread in objects

Use spread to copy an object or merge objects together.

const user = {name:"Amina",city:"Podgorica" };
const userCopy = { ...user };

console.log(userCopy);
// { name: "Amina", city: "Podgorica" }

Merging two objects looks like this:

const defaultSettings = {theme:"dark",notifications:true };
const userSettings = {notifications:false };

const finalSettings = { ...defaultSettings, ...userSettings };

console.log(finalSettings);
// { theme: "dark", notifications: false }

If two objects contain the same key, the later one overrides the earlier one.

Spread in function calls

Spread is handy when a function expects separate values, but you already have them inside an array.

const numbers = [4,8,15];

const maxValue =Math.max(...numbers);
console.log(maxValue);
// 15

Spread in strings

Strings are iterable, so spread turns them into an array of characters.

const word ="Mimo";
const letters = [...word];

console.log(letters);
// ["M", "i", "m", "o"]

Spread in array destructuring

You’ll often see spread used as a “collect the rest” tool inside destructuring.

const colors = ["purple","orange","blue","green"];

const [first, second, ...rest] = colors;

console.log(first);// "purple"
console.log(second);// "orange"
console.log(rest);// ["blue", "green"]

That part is technically called the rest pattern, but it uses the same ... syntax, so it’s easy to mix them up.

When to Use the Spread Operator

The spread operator saves you from a lot of messy code and makes your intent obvious. Here are some situations where it shines.

1) Copying arrays or objects without side effects

If you update a copied array or object, you don’t want to accidentally change the original too. Spread gives you a clean “new copy” in one line.

2) Merging data together

You can combine arrays, merge objects, or layer settings like defaults plus overrides. The result reads like a sentence: “take these, then add those.”

3) Updating state in UI frameworks

React and other UI libraries often prefer immutable updates. Spread helps you create new arrays and objects instead of editing the old ones in place.

4) Converting array-like values into real arrays

Some values look like arrays but aren’t, like NodeList from querySelectorAll(). Spread can convert them quickly.

5) Making function calls cleaner

Functions like Math.max() or Math.min() feel awkward with arrays. Spread solves that instantly.

Examples of the Spread Operator

Example 1: Adding an item to an array without mutating it

Imagine you have a shopping list and want to add one more item.

const shoppingList = ["milk","bread","apples"];
const updatedList = [...shoppingList,"tea"];

console.log(updatedList);
// ["milk", "bread", "apples", "tea"]

console.log(shoppingList);
// ["milk", "bread", "apples"]

That keeps the original list untouched, which is helpful when multiple parts of your program still rely on it.

Example 2: Combining multiple arrays into one

Let’s say you’re building a music playlist from two sources.

const chillSongs = ["Midnight Walk","Soft Rain"];
const workoutSongs = ["Fast Lane","Push Hard"];

const playlist = [...chillSongs, ...workoutSongs];

console.log(playlist);
// ["Midnight Walk", "Soft Rain", "Fast Lane", "Push Hard"]

Example 3: Updating an object field

You often want to update one field while keeping the rest of the object the same.

const profile = {
name:"Jordan",
role:"Designer",
online:false
};

const updatedProfile = { ...profile,online:true };

console.log(updatedProfile);
// { name: "Jordan", role: "Designer", online: true }

This style is great for things like “toggle online status” or “change theme.”

Example 4: Merging configuration settings

Sometimes you have defaults, then you apply user overrides.

const defaults = {
language:"en",
showTips:true,
fontSize:"medium"
};

const overrides = {
showTips:false,
fontSize:"large"
};

const settings = { ...defaults, ...overrides };

console.log(settings);
// { language: "en", showTips: false, fontSize: "large" }

The final object reads like “start with defaults, then override what the user changed.”

Example 5: Turning a NodeList into an array

The result of document.querySelectorAll() looks like a list, but it’s not a real array.

const buttons =document.querySelectorAll("button");
const buttonArray = [...buttons];

buttonArray.forEach((btn) => {
  btn.addEventListener("click",() => {
console.log("Clicked!");
  });
});

Spread makes it easy to use array methods like forEach() or map() without extra conversions.

Example 6: Copying nested data (the part that trips people up)

Spread creates a shallow copy, which means nested objects still point to the same place in memory.

const original = {
name:"Sam",
stats: {wins:3 }
};

const copy = { ...original };
copy.stats.wins =99;

console.log(original.stats.wins);
// 99 (surprise!)

That “surprise” is real, and it causes bugs in apps that assume spread copies everything deeply.

Learn More About the Spread Operator

Spread vs rest syntax

The spread operator and rest pattern look identical (...), but they do opposite jobs:

  • Spread expands values out
  • Rest collects values in

Spread example:

const nums = [1,2,3];
console.log(...nums);
// 1 2 3

Rest example:

constsum = (...numbers) => {
return numbers.reduce((total, n) => total + n,0);
};

console.log(sum(5,10,15));
// 30

In that function, ...numbers collects all arguments into an array.

Common mistake: using spread on non-iterables

Spread works on iterables like arrays and strings. It doesn’t work on plain objects inside array positions like this:

// This throws an error because {} is not iterable
// const values = [...{ a: 1 }];

Objects can be spread only in object literal context:

const obj = {a:1,b:2 };
const merged = { ...obj,c:3 };

Copying arrays and objects safely

Spread is the fastest “good enough” tool for many cases, but it won’t deep copy nested structures.

If you need a deep copy, you have a few options:

  • Manually copy nested pieces with more spread operators
  • Use structuredClone() (modern browsers and Node support it)
  • Use a library if the data is complex

Here’s a simple nested copy using spread:

const state = {
user: {name:"Lina" },
favorites: ["React","TypeScript"]
};

const updatedState = {
  ...state,
user: { ...state.user,name:"Lina K." }
};

console.log(updatedState.user.name);
// "Lina K."

Spread in array methods and patterns

You’ll see spread in common patterns like:

  • cloning before sorting, so the original stays the same
  • inserting items in the middle
  • removing items by slicing and rebuilding

Example: clone before sorting

const scores = [50,10,40];
const sortedScores = [...scores].sort((a, b) => a - b);

console.log(scores);
// [50, 10, 40]

console.log(sortedScores);
// [10, 40, 50]

Performance note (without overthinking it)

Spread is great for small-to-medium data. If you’re copying huge arrays in a tight loop, it can slow things down.

Most projects won’t hit that problem, but if your laptop fan starts sounding like it’s trying to take off, that’s one place to look.

Summary

The spread operator (...) expands arrays, objects, and strings into individual values. Use it to copy data, merge arrays and objects, update state cleanly, and pass array values into functions without extra steps.