Spread vs Rest Operators in JavaScript
JavaScript has evolved a lot over the years, and one of the most useful additions in modern JavaScript (ES6 and beyond) is the spread (...) and rest (...) operators. Interestingly, both operators use the same syntax (...), but they behave differently depending on how and where they are used.
If you’re preparing for interviews, working on real-world projects, or just trying to write cleaner and more efficient code, understanding these operators is essential.
In this blog, we’ll cover:
What the spread operator does
What the rest operator does
Differences between spread and rest
Using spread with arrays and objects
Practical real-world use cases
Easy examples to understand the concept clearly
🔹 What is the Spread Operator?
The spread operator (...) is used to expand elements of an array, object, or iterable into individual elements.
👉 Think of it like unpacking or spreading out values.
✅ Basic Example (Array)
const arr = [1, 2, 3];
const newArr = [...arr];
console.log(newArr); // [1, 2, 3]
Here, ...arr spreads the elements into a new array.
🔍 Diagram Idea: Spread Expanding Values
[1, 2, 3] ---> ... ---> 1, 2, 3
✅ Combining Arrays
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4]
✅ Copying Arrays (Shallow Copy)
const original = [10, 20, 30];
const copy = [...original];
copy[0] = 99;
console.log(original); // [10, 20, 30]
console.log(copy); // [99, 20, 30]
🔹 Spread Operator with Objects
Spread also works with objects to copy or merge them.
✅ Example
const user = {
name: "Kanishka",
age: 21
};
const updatedUser = {
...user,
city: "Meerut"
};
console.log(updatedUser);
// { name: "Kanishka", age: 21, city: "Meerut" }
✅ Merging Objects
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 2 }
🔹 What is the Rest Operator?
The rest operator (...) is used to collect multiple elements into a single array or object.
👉 Think of it like packing values together.
🔍 Diagram Idea: Rest Collecting Values
1, 2, 3 ---> ... ---> [1, 2, 3]
✅ Example with Function Parameters
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(5, 10)); // 15
Here, ...numbers collects all arguments into an array.
✅ Example with Array Destructuring
const arr = [1, 2, 3, 4];
const [first, ...rest] = arr;
console.log(first); // 1
console.log(rest); // [2, 3, 4]
✅ Example with Objects
const user = {
name: "Kanishka",
age: 21,
city: "Meerut"
};
const { name, ...rest } = user;
console.log(name); // Kanishka
console.log(rest); // { age: 21, city: "Meerut" }
🔹 Key Difference: Spread vs Rest
Although both use ..., their purpose is completely different.
| Feature | Spread Operator | Rest Operator |
|---|---|---|
| Purpose | Expands elements | Collects elements |
| Direction | Inside → Outside | Outside → Inside |
| Usage | Arrays, Objects, Function calls | Function params, Destructuring |
| Output | Individual elements | Array/Object |
🔥 Simple Way to Remember
Spread = Expand (break things apart)
Rest = Collect (bring things together)
🔹 Using Spread in Real-World Scenarios
Let’s move beyond basic examples and look at real-world usage.
✅ 1. Updating State (React-style thinking)
const user = { name: "Kanishka", age: 21 };
const updatedUser = {
...user,
age: 22
};
✔️ Instead of modifying the original object, we create a new one (important in modern frameworks).
✅ 2. Adding Elements to an Array
const arr = [1, 2, 3];
const newArr = [...arr, 4];
console.log(newArr); // [1, 2, 3, 4]
✅ 3. Removing Elements (Immutability)
const arr = [1, 2, 3, 4];
const newArr = arr.slice(1); // OR using spread
const newArr2 = [...arr].slice(1);
console.log(newArr2); // [2, 3, 4]
✅ 4. Passing Array as Function Arguments
const numbers = [1, 2, 3];
function add(a, b, c) {
return a + b + c;
}
console.log(add(...numbers)); // 6
🔹 Using Rest in Real-World Scenarios
✅ 1. Flexible Function Arguments
function greet(greeting, ...names) {
names.forEach(name => {
console.log(`\({greeting}, \){name}`);
});
}
greet("Hello", "Kanishka", "Yash", "Rahul");
✅ 2. Ignoring Certain Values
const [first, ...others] = [10, 20, 30, 40];
console.log(first); // 10
console.log(others); // [20, 30, 40]
✅ 3. Extracting Important Data from Objects
const student = {
name: "Kanishka",
marks: 90,
grade: "A",
school: "XYZ"
};
const { name, ...details } = student;
console.log(details);
// { marks: 90, grade: "A", school: "XYZ" }
🔹 Common Mistakes to Avoid
❌ 1. Confusing Spread and Rest
function test(...args) {} // Rest
const arr = [...args]; // Spread
❌ 2. Using Rest Not at the Last Position
// ❌ Wrong
const [a, ...rest, b] = [1, 2, 3];
// ✅ Correct
const [a, ...rest] = [1, 2, 3];
❌ 3. Shallow Copy Confusion
Spread creates a shallow copy, not a deep copy.
const obj = { a: 1, b: { c: 2 } };
const copy = { ...obj };
copy.b.c = 99;
console.log(obj.b.c); // 99 (changed!)
🔹 When to Use Spread vs Rest
Use Spread When:
You want to copy arrays/objects
You want to merge data
You want to pass multiple values
Use Rest When:
You want flexible function arguments
You want to collect remaining values
You want to destructure data cleanly