Explain the spread and rest operators. When would you use each?
3 minintermediatejavascriptes6spreadrestoperators
Quick Answer
The spread (...) and rest (...) operators use the same syntax but serve different purposes depending on context.
Detailed Answer
Explain the spread and rest operators. When would you use each?
The spread (...) and rest (...) operators use the same syntax but serve different purposes depending on context.
Spread Operator (...):
Expands an iterable (array, string, object) into individual elements.
Array Spread:
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// Combine arrays
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// Add elements
const withExtra = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// Clone array
const cloned = [...arr1]; // [1, 2, 3] - shallow copy
// Convert string to array
const chars = [...'hello']; // ['h', 'e', 'l', 'l', 'o']
// Function arguments
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
Object Spread:
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
// Combine objects
const combined = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
// Override properties
const updated = { ...obj1, b: 10 }; // { a: 1, b: 10 }
// Clone object
const cloned = { ...obj1 }; // { a: 1, b: 2 } - shallow copy
// Add properties
const withExtra = { ...obj1, e: 5 }; // { a: 1, b: 2, e: 5 }
Rest Operator (...):
Collects multiple elements into a single variable.
Function Parameters:
// Collect remaining arguments
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
// Mix with regular parameters
function greet(greeting, ...names) {
return `${greeting} ${names.join(', ')}!`;
}
console.log(greet('Hello', 'John', 'Jane', 'Bob')); // "Hello John, Jane, Bob!"
Array Destructuring:
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
// Skip elements
const [a, , ...remaining] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(remaining); // [3, 4, 5]
Object Destructuring:
const { name, ...otherProps } = { name: 'John', age: 30, city: 'NYC' };
console.log(name); // 'John'
console.log(otherProps); // { age: 30, city: 'NYC' }
Practical Use Cases:
- Array Manipulation:
// Remove duplicates
const unique = [...new Set([1, 2, 2, 3, 3, 4])]; // [1, 2, 3, 4]
// Insert at specific position
function insertAt(array, index, ...items) {
return [...array.slice(0, index), ...items, ...array.slice(index)];
}
const result = insertAt([1, 2, 5], 2, 3, 4); // [1, 2, 3, 4, 5]
- Object Updates:
// Immutable updates
const updateUser = (user, updates) => ({ ...user, ...updates });
const user = { name: 'John', age: 30 };
const updated = updateUser(user, { age: 31, city: 'NYC' });
// { name: 'John', age: 31, city: 'NYC' }
- React State Updates:
// Add item to array
const addItem = (items, newItem) => [...items, newItem];
// Remove item from array
const removeItem = (items, id) => items.filter(item => item.id !== id);
// Update object in array
const updateItem = (items, id, updates) =>
items.map(item => item.id === id ? { ...item, ...updates } : item);
- API Calls:
// Merge query parameters
const buildUrl = (baseUrl, ...params) => {
const queryString = params.join('&');
return `${baseUrl}?${queryString}`;
};
const url = buildUrl('/api/users', 'page=1', 'limit=10', 'sort=name');