⬅ Previous Topic
JavaScript Iterating Over ObjectsNext Topic ⮕
JavaScript DOM Tree⬅ Previous Topic
JavaScript Iterating Over ObjectsNext Topic ⮕
JavaScript DOM TreeIn JavaScript, the ...
(three dots) syntax serves two distinct purposes — it can either expand or collect elements. These two operations are called the spread operator and the rest operator respectively.
Though they look identical, the intent changes based on where and how you use them. This guide breaks down both, starting from the basics and climbing to more advanced use cases.
The spread operator allows an iterable like an array or string to be expanded into its individual elements. It is mostly used in arrays, objects, and function calls.
const nums = [1, 2, 3];
const extended = [...nums, 4, 5];
console.log(extended);
[1, 2, 3, 4, 5]
[...nums]
spreads the original array’s values into a new one, after which 4
and 5
are added. This is useful for non-mutating operations.
You can also pass array elements as individual arguments to a function.
function sum(a, b, c) {
return a + b + c;
}
const values = [10, 20, 30];
console.log(sum(...values));
60
Spread isn’t limited to arrays. You can use it to copy or merge objects too.
const obj1 = { name: "John", age: 25 };
const obj2 = { ...obj1, city: "New York" };
console.log(obj2);
{ name: "John", age: 25, city: "New York" }
Spread is perfect for creating shallow copies:
const original = { brand: "Toyota", model: "Corolla" };
const copy = { ...original };
console.log(copy);
{ brand: "Toyota", model: "Corolla" }
Spread creates only a shallow copy. Nested objects are still referenced:
const deep = { user: { name: "Alice" } };
const copy = { ...deep };
copy.user.name = "Bob";
console.log(deep.user.name);
Bob
Why? Because copy.user
points to the same memory location as deep.user
. For deep cloning, use libraries like Lodash or structured cloning.
While spread expands, rest collects multiple elements into a single one. It's often used in function parameters and destructuring.
function total(...numbers) {
return numbers.reduce((sum, curr) => sum + curr, 0);
}
console.log(total(5, 10, 15));
30
Here, numbers
becomes an array containing all arguments passed to total
.
You can use rest to gather remaining values during array destructuring:
const [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 1
console.log(rest); // [2, 3, 4]
Rest can also be used to exclude specific properties when copying objects:
const person = { name: "Sam", age: 40, city: "Delhi" };
const { name, ...details } = person;
console.log(name); // Sam
console.log(details); // { age: 40, city: "Delhi" }
Let’s say you receive users from two different APIs. You want to combine them into one:
const apiUsers1 = [{ id: 1 }, { id: 2 }];
const apiUsers2 = [{ id: 3 }, { id: 4 }];
const allUsers = [...apiUsers1, ...apiUsers2];
console.log(allUsers);
[{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
Understanding the context is the real trick. If the dots are used on the left-hand side of an assignment or in a function parameter list, it's rest. If on the right, it's spread.
⬅ Previous Topic
JavaScript Iterating Over ObjectsNext Topic ⮕
JavaScript DOM TreeYou can support this website with a contribution of your choice.
When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.