Spread vs Rest Operators in JavaScript

In JavaScript, the spread operator (...) expands values (breaks them apart), while the rest operator (...) collects values (packs them together). They look identical but behave oppositely depending on context.
Spread Operator
The spread operator (...) in JavaScript is a syntax that lets you expand an array, object, or iterable into individual elements. It’s like opening up a box and laying out everything inside.
How It Works
Arrays: Expands elements into a new array or function call.
Objects: Expands properties into a new object.
Function calls: Expands an array into separate arguments.
1. Expanding Arrays
const arr = [1, 2, 3];
const newArr = [...arr, 4, 5];
console.log(newArr); // [1, 2, 3, 4, 5]
2. Passing Arguments
function add(a, b, c) {
return a + b + c;
}
const nums = [10, 20, 30];
console.log(add(...nums)); // 60
3. Copying & Merging Objects
const user = { name: "Rohit" };
const updated = { ...user, age: 25 };
console.log(updated); // { name: "Rohit", age: 25 }
Rest Operator
The rest operator helps to condense all the values together in an array and pass it as an argument .
As i said that the it collects multiple items and convert into one array or object.
Array Destructuring :-
While destructuring an array the order is very important because whenever you use the rest operator the remaining elements are converted into an array.
const colors = ["red", "green", "blue", "yellow", "purple"];
// Extract 'red' and 'green', then collect the 'rest'
const [first, second, ...remaining] = colors;
console.log(first); // "red"
console.log(remaining); // ["blue", "yellow", "purple"]
This is how it looks a new array is generated which is having the all remaining elements as an elements.
Object Destructuring :-
Similarly while destructuring the object if you want to create an another object which is lacking some elements you can easily create using the rest operator.
const student = {
name: "Arjun",
age: 20,
city: "Pune",
college: "SPPU",
major: "Computer Science"
};
// Extract 'name', and keep everything else in 'academicDetails'
const { name, ...academicDetails } = student;
console.log(name); // "Arjun"
console.log(academicDetails); // { age: 20, city: "Pune", college: "SPPU", major: "Computer Science" }
What’s happening "under the hood"?
Creation of a Shallow Copy: The rest operator doesn't just point to the old data; it creates a new array or object. However, it is a shallow copy, meaning if you have nested objects inside, they are still referenced.
Things to know about these operators :
1. The "Shallow Copy" Caveat
Most beginners think const clone = [...original] creates a completely independent copy. This is a half-truth. It creates a shallow copy.
- The Deep Detail: The spread operator copies values of primitives (strings, numbers) but only copies references for objects or nested arrays.
The Example:
const original = [{ name: "Arjun" }];
const copy = [...original];
copy[0].name = "Changed";
console.log(original[0].name); // "Changed" - They still share the same nested object!
2. Performance: Spread vs. Object.assign
In a technical deep dive, it's worth noting that while ... is modern and readable, it isn't always the fastest for massive objects in high-frequency loops.
- The Deep Detail: The spread operator creates a new object literal, which engines like V8 optimize very well. However,
Object.assign()can sometimes be faster if you are merging more than 3-4 objects at once because it modifies the target object rather than creating new literals at every intermediate step.
3. String to Array Conversion
One of the "coolest" uses of spread is how it handles iterables. Since strings are iterable, you can use the spread operator to turn a string into an array of characters instantly.
The Deep Detail: This is better than .split('') because the spread operator is Unicode-aware. It handles complex emojis and special characters better than the older string methods.
const str = "Hello 🚀";
const chars = [...str];
// Works perfectly with the emoji!
4. Edge Case: Spread with null or undefined
This is a common interview question or "gotcha" :
Spreading in an Object:
{ ...null }or{ ...undefined }simply results in an empty object{}. It does not throw an error.Spreading in an Array:
[ ...null ]will throw a TypeError becausenullis not iterable.Why? Objects have a different internal "copy" logic than arrays (which require an Iterator).
Conclusion
he beauty of the ... syntax lies in its uses. Whether you are gathering loose data into an organized array (Rest) or distributing a collection into individual pieces (Spread), these operators make your JavaScript code more readable, modern, and immutable.
The Golden Rule to Remember:
Rest is for receiving: It packs multiple items into one box.
Spread is for sending: It unpacks one box into multiple items.
By mastering these three little dots, you aren’t just writing shorter code—you’re writing "cleaner" code that handles data with the precision required for modern Full-Stack development.



