Destructuring, Spread & Rest Operators in JavaScript
Yesterday, I explored Functional Programming in JavaScript and learned how functions can be passed around as values and how methods like map(), filter(), and reduce() can transform data.
Today, I learned three powerful features of modern JavaScript:
Destructuring
Spread Operator
Rest Operator
These features are especially useful when working with arrays, objects, function parameters, and API responses.
They help make JavaScript code shorter, cleaner, and easier to read.
Let's dive in.
What is Destructuring?
Destructuring allows us to extract values from arrays or properties from objects and assign them to variables.
Instead of:
const user = {
name: "Saurabh",
age: 22
};
const name = user.name;
const age = user.age;
we can write:
const user = {
name: "Saurabh",
age: 22
};
const { name, age } = user;
console.log(name);
console.log(age);
This makes accessing object properties much cleaner.
Object Destructuring
Suppose we have:
const developer = {
name: "Saurabh",
role: "Developer",
experience: 1
};
We can destructure:
const {
name,
role,
experience
} = developer;
Now we can directly use:
console.log(name);
console.log(role);
console.log(experience);
Renaming Destructured Variables
Sometimes the property name isn't the name we want to use.
We can rename it:
const user = {
name: "Saurabh"
};
const {
name: userName
} = user;
console.log(userName);
Here:
name → userName
Default Values
We can provide a default value when a property doesn't exist.
const user = {
name: "Saurabh"
};
const {
name,
role = "Developer"
} = user;
console.log(role);
Output:
Developer
The default value is used because role doesn't exist.
Nested Destructuring
We can also destructure nested objects.
const user = {
name: "Saurabh",
address: {
city: "Mumbai",
country: "India"
}
};
We can write:
const {
address: {
city,
country
}
} = user;
Now:
console.log(city);
console.log(country);
Nested destructuring is particularly useful when working with structured API responses.
Array Destructuring
Destructuring also works with arrays.
const colors = [
"red",
"green",
"blue"
];
const [
first,
second,
third
] = colors;
console.log(first);
console.log(second);
console.log(third);
Output:
red
green
blue
Array destructuring is based on position, unlike object destructuring, which is based on property names.
Skipping Array Values
We can skip elements using commas.
const numbers = [
10,
20,
30
];
const [
first,
,
third
] = numbers;
console.log(first);
console.log(third);
Output:
10
30
Swapping Variables
Array destructuring provides a clean way to swap values.
Instead of using a temporary variable:
let a = 10;
let b = 20;
[a, b] = [b, a];
console.log(a);
console.log(b);
Output:
20
10
This is a very useful JavaScript pattern.
What is the Spread Operator?
The spread operator is written as:
...
It expands an iterable such as an array or the properties of an object.
For example:
const numbers = [1, 2, 3];
const newNumbers = [
...numbers,
4,
5
];
console.log(newNumbers);
Output:
[1, 2, 3, 4, 5]
Combining Arrays With Spread
Without spread:
const first = [1, 2, 3];
const second = [4, 5, 6];
const combined = [
first,
second
];
This creates a nested array:
[[1, 2, 3], [4, 5, 6]]
With spread:
const combined = [
...first,
...second
];
We get:
[1, 2, 3, 4, 5, 6]
Copying an Array
Spread can create a shallow copy of an array.
const original = [
"HTML",
"CSS",
"JavaScript"
];
const copy = [
...original
];
Now copy is a separate array.
However, remember that this is a shallow copy. Nested objects or arrays are still shared references.
Spread With Objects
Spread also works with objects.
const user = {
name: "Saurabh",
age: 22
};
const updatedUser = {
...user,
role: "Developer"
};
Now:
console.log(updatedUser);
gives:
{
name: "Saurabh",
age: 22,
role: "Developer"
}
Updating Object Properties
Spread is particularly useful when creating an updated object without mutating the original.
const user = {
name: "Saurabh",
age: 22
};
const updatedUser = {
...user,
age: 23
};
The original object remains unchanged.
This pattern is extremely important when working with React state.
What is the Rest Operator?
The rest operator also uses:
...
But instead of expanding values, it collects remaining values into an array or object.
Example:
const numbers = [
1,
2,
3,
4,
5
];
const [
first,
second,
...rest
] = numbers;
console.log(first);
console.log(second);
console.log(rest);
Output:
1
2
[3, 4, 5]
Rest Parameters in Functions
Rest can collect an arbitrary number of function arguments.
function sum(...numbers) {
return numbers.reduce(
(total, number) => total + number,
0
);
}
console.log(
sum(10, 20, 30, 40)
);
Output:
100
Here:
...numbers
collects all arguments into an array.
Rest With Objects
Rest can also collect remaining object properties.
const user = {
name: "Saurabh",
age: 22,
role: "Developer"
};
const {
name,
...details
} = user;
console.log(name);
console.log(details);
Output:
Saurabh
{
age: 22,
role: "Developer"
}
Spread vs Rest
The syntax is the same:
...
But the purpose depends on where it is used.
Spread
Expands values.
const combined = [
...array1,
...array2
];
Rest
Collects remaining values.
const [
first,
...remaining
] = numbers;
A simple way to remember:
Spread → Expand
Rest → Collect
Destructuring Function Parameters
Destructuring can also be used directly in function parameters.
function displayUser({ name, age }) {
console.log(name);
console.log(age);
}
displayUser({
name: "Saurabh",
age: 22
});
This is especially common when working with objects passed into functions.
Combining Everything
We can combine destructuring, spread, and rest.
const user = {
name: "Saurabh",
age: 22,
skills: [
"HTML",
"CSS",
"JavaScript"
]
};
const {
name,
...details
} = user;
const updatedUser = {
...details,
experience: 1
};
console.log(name);
console.log(updatedUser);
These features allow us to work with data in a very expressive way.
Best Practices
✔ Use destructuring when it makes object and array access clearer.
✔ Use spread when creating shallow copies or combining arrays/objects.
✔ Use rest when collecting an unknown number of values.
✔ Remember that spread creates shallow copies.
✔ Don't overuse nested destructuring if it makes the code difficult to read.
✔ Use meaningful variable names when destructuring.
My Biggest Takeaway
Today, I learned three features that appear constantly in modern JavaScript:
Destructuring → Extract
Spread → Expand
Rest → Collect
These features make working with arrays, objects, function parameters, and API responses much cleaner.
The most important realization for me was that these aren't just shortcuts—they encourage cleaner ways of handling data without unnecessarily mutating the original values.
And because React relies heavily on immutable updates and object/array transformations, these concepts will become extremely useful when I start building React applications.
