Spread Operator
This lesson explains Spread Operator with clear examples, use cases, and best practices so you can use modern JavaScript confidently in real projects.
ES6+ Spread Operator Overview
The spread operator uses three dots (...) to expand
an iterable such as an array, string, or object into individual
elements. It is one of the most useful ES6 features for copying,
merging, and passing values cleanly.
Spread syntax is commonly used to clone arrays, combine objects,
pass array items as function arguments, and create immutable state
updates in modern JavaScript applications.
| Feature | Description |
| Introduced In | ES6 (ECMAScript 2015) |
| Syntax | ... |
| Works With | Arrays, objects, strings, iterables |
| Main Uses | Copy, merge, expand, pass arguments |
| Copy Type | Shallow copy |
| Related Feature | Rest parameters |
Basic Spread Operator Example
const numbers = [1, 2, 3];
const moreNumbers = [
0,
...numbers,
4
];
console.log(moreNumbers);
function add(a, b, c) {
return a + b + c;
}
console.log(
add(...numbers)
);
Spread expands numbers into individual values inside a
new array and as separate arguments to the add()
function.
How the Spread Operator Works
The spread operator unpacks values from an iterable and places them
where individual elements are expected, such as inside an array
literal, object literal, or function call.
| Step | Description | Example Syntax |
| Start with Iterable | Use an array, object, or string. | const items = [1, 2, 3] |
| Apply Spread | Expand values with .... | [...items] |
| Create New Value | Build a new array or object. | [0, ...items, 4] |
| Pass Arguments | Send values into a function. | fn(...items) |
| Keep Original Safe | Original data remains unchanged. | items stays the same |
Copy an Array
const original = [10, 20, 30];
const copy = [...original];
copy.push(40);
console.log(original);
console.log(copy);
[...array] creates a shallow copy of an array. Changes
to the copy do not affect the original top-level array.
Merge Arrays
const frontend = [
"HTML",
"CSS",
"JavaScript"
];
const backend = [
"Node.js",
"Express"
];
const fullStack = [
...frontend,
"Git",
...backend
];
console.log(fullStack);
Spread makes merging arrays simple and readable compared with
concat() chains.
Spread with Objects
const user = {
name: "Alex",
role: "admin"
};
const updatedUser = {
...user,
role: "editor",
theme: "dark"
};
console.log(user);
console.log(updatedUser);
Object spread copies properties into a new object. Later properties
overwrite earlier ones with the same key, which is useful for
immutable updates.
Pass Function Arguments
const scores = [88, 95, 72, 91];
console.log(
Math.max(...scores)
);
function greet(first, second, third) {
return `${first}, ${second}, ${third}`;
}
const names = ["Alex", "Sam", "Riya"];
console.log(
greet(...names)
);
Spread is especially helpful when a function expects separate
arguments but your data is stored in an array.
Spread a String into Characters
const word = "code";
const letters = [...word];
console.log(letters);
console.log(letters.join("-"));
Strings are iterable, so spread syntax can convert them into arrays
of characters quickly.
Immutable State Update
const cart = [
{ id: 1, name: "Keyboard" },
{ id: 2, name: "Mouse" }
];
const newCart = [
...cart,
{ id: 3, name: "Monitor" }
];
const settings = {
theme: "light",
language: "en"
};
const nextSettings = {
...settings,
theme: "dark"
};
console.log(cart);
console.log(newCart);
console.log(nextSettings);
Spread is widely used in React, Redux, and other state-driven apps
to update arrays and objects without mutating the previous state.
Understand Shallow Copying
const original = [
{ id: 1, active: true }
];
const copy = [...original];
copy[0].active = false;
console.log(original[0].active);
console.log(copy[0].active);
Spread creates a shallow copy. Nested objects are still shared by
reference, so changing nested data affects both copies unless you
clone deeper levels too.
Spread vs Rest Operator
// Spread: expands values
const nums = [1, 2, 3];
console.log([...nums]);
// Rest: collects values
function total(...values) {
return values.reduce(
(sum, value) => sum + value,
0
);
}
console.log(total(1, 2, 3, 4));
Spread and rest use the same ... syntax, but spread
expands values outward while rest collects values into an array.
Common Spread Operator Use Cases
| Use Case | Example | Purpose |
| Copy array | [...items] | Create a new array. |
| Merge arrays | [...a, ...b] | Combine lists. |
| Clone object | { ...obj } | Create a new object. |
| Update object | { ...obj, key: value } | Immutable property update. |
| Function args | fn(...values) | Pass array items as arguments. |
| Convert string | [..."text"] | Split into characters. |
Practical Spread Operator Examples
- Adding items to a shopping cart array immutably.
- Merging default settings with user preferences.
- Passing dynamic argument lists to
Math.max(). - Cloning arrays before sorting or reversing.
- Combining multiple tag lists or category arrays.
- Updating one property in a state object without mutation.
Spread Operator Best Practices
- Use spread for shallow copies and simple merges.
- Place spread properties before overrides in object updates.
- Prefer spread over manual loops for readable array/object merging.
- Remember that nested data is still shared in shallow copies.
- Use spread with function calls when arguments are stored in arrays.
- Combine spread with destructuring for clean data transformations.
- Do not use spread on
null or undefined.
Common Spread Operator Mistakes
- Expecting spread to deeply clone nested objects or arrays.
- Putting override properties before spread in objects and losing updates.
- Confusing spread with rest parameters.
- Trying to spread non-iterable values.
- Assuming copied arrays are fully independent when nested references exist.
- Using spread where mutation is actually intended and safe.
- Forgetting that object spread only copies enumerable own properties.
Spread vs concat and Object.assign
| Task | Spread Syntax | Older Alternative |
| Merge arrays | [...a, ...b] | a.concat(b) |
| Copy array | [...a] | a.slice() |
| Merge objects | { ...a, ...b } | Object.assign({}, a, b) |
| Function args | fn(...args) | fn.apply(null, args) |
Key Takeaways
- The spread operator expands iterables with
... syntax. - It is commonly used to copy, merge, and pass values in modern JavaScript.
- Array and object spread help create immutable updates cleanly.
- Spread performs shallow copying, not deep cloning.
- Spread expands values, while rest collects values into an array.
Pro Tip
For object updates, write
{ ...original, changedField: newValue } so
the spread comes first and only the fields you list afterward are
overridden.