Spread Operator
Spread Operator
The spread operator (...) expands an iterable into individual elements.
Arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// Concatenation
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// Copy
const copy = [...arr1]; // [1, 2, 3]
// Add elements
const withNew = [...arr1, 4]; // [1, 2, 3, 4]
const withNewAtStart = [0, ...arr1]; // [0, 1, 2, 3]
Objects
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
// Merge
const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
// Copy
const copy = { ...obj1 };
// Override
const updated = { ...obj1, b: 20 }; // { a: 1, b: 20 }
Function Arguments
const numbers = [1, 2, 3, 4, 5];
// Pass array as arguments
Math.max(...numbers); // 5
console.log(...numbers); // 1 2 3 4 5
Strings
const str = 'hello';
const chars = [...str]; // ['h', 'e', 'l', 'l', 'o']
Objects with Same Keys
const defaults = { color: 'red', size: 'medium' };
const custom = { color: 'blue' };
// custom overrides defaults
const result = { ...defaults, ...custom };
// { color: 'blue', size: 'medium' }
Spread vs Object.assign
// Object.assign (mutates target)
const target = { a: 1 };
Object.assign(target, { b: 2 });
// Spread (creates new)
const original = { a: 1 };
const copy = { ...original, b: 2 };
Rest Parameters
Rest Parameters
Rest parameters collect remaining elements into an array.
In Function Parameters
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3); // 6
sum(1, 2, 3, 4); // 10
With Other Parameters
function log(level, ...messages) {
console.log(level, ...messages);
}
log('INFO', 'Server', 'started', 'on', 'port', '3000');
In Destructuring
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]
const { name, ...details } = { name: 'John', age: 30, city: 'NYC' };
console.log(name); // "John"
console.log(details); // { age: 30, city: 'NYC' }
Arguments Object vs Rest
// Old: arguments object
function oldSum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
// Modern: rest parameters
function newSum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
Rest in Arrow Functions
const sum = (...numbers) =>
numbers.reduce((total, n) => total + n, 0);
sum(1, 2, 3); // 6
Rest Must Be Last
// Correct
function fn(a, b, ...rest) { }
// Error
function fn(...rest, a, b) { }
Practical Examples
Practical Examples
Immutability Patterns
// Add to array
const arr = [1, 2, 3];
const newArr = [...arr, 4]; // [1, 2, 3, 4]
// Remove from array
const index = 1;
const withoutItem = arr.filter((_, i) => i !== index);
// Update in array
const updated = arr.map(item =>
item === 2 ? 20 : item
);
// Add to object
const obj = { a: 1, b: 2 };
const newObj = { ...obj, c: 3 };
// Remove from object
const { a, ...rest } = obj; // rest is { b: 2 }
// Update in object
const updatedObj = { ...obj, b: 20 };
shallow Clone Patterns
// Array clone
const clone = [...original];
// Object clone
const clone = { ...original };
// Shallow clone (top level only)
const shallow = { ...original };
deep.nested.value = 'changed'; // Affects original!
Function Arguments
// Pass array as arguments
const args = [1, 2, 3];
Math.max(...args);
// Combine with other args
function log(prefix, ...messages) {
console.log(prefix, ...messages);
}
Array Flattening
const nested = [[1, 2], [3, 4], [5]];
const flat = nested.flat(); // [1, 2, 3, 4, 5]
// Manual flatten with spread
const flat = [].concat(...nested);
Object Merging
// Deep merge (simple)
deepMerge(obj1, obj2);
function deepMerge(target, source) {
return {
...target,
...Object.fromEntries(
Object.entries(source).map(([key, val]) => [
key,
typeof val === 'object' && val !== null
? deepMerge(target[key] || {}, val)
: val
])
)
};
}
Performance Considerations
// Spread creates new objects/arrays
const arr = [1, 2, 3];
const copy = [...arr]; // New array!
// For large arrays, consider:
const copy = arr.slice(); // Slightly faster
// For objects:
const copy = Object.assign({}, obj); // Or spread
Practice Problems
Create a reusable React component implementing Spread and Rest. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Spread and Rest using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Spread and Rest for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What does the spread operator do?
2. What is the difference between spread and rest?
3. What must rest parameters be in a function?
4. How do you copy an array with spread?
5. What happens with duplicate keys when spreading objects?
Flashcards
Question
What does ... (spread) do?
Click to reveal answer
Answer
Expands an iterable into individual elements: [1, ...[2,3]] = [1,2,3]
Question
What do rest parameters do?
Click to reveal answer
Answer
Collect remaining function arguments into an array: function sum(...nums) {}
Question
What is the difference between spread and rest?
Click to reveal answer
Answer
Spread expands iterables. Rest collects into arrays. Same syntax, opposite purposes.
Question
How do you shallow copy an object with spread?
Click to reveal answer
Answer
const copy = { ...original };
Question
Can rest parameters be first in a function?
Click to reveal answer
Answer
No, rest parameters must be the last parameter in a function signature.
Revision Notes
Key Takeaways
- 1.Spread expands, rest collects
- 2.Both use the same ... syntax
- 3.Rest must be last in function parameters
- 4.Spread creates shallow copies
- 5.Later object keys overwrite earlier ones
Interview Tips
- •Explain the difference between spread and rest
- •Know how to use spread for copying
- •Understand rest in function parameters
- •Be able to merge objects with spread
Cheat Sheet
Spread and Rest Cheat Sheet
Spread (...)
// Arrays
const arr = [...arr1, ...arr2];
const copy = [...arr];
// Objects
const obj = { ...obj1, ...obj2 };
const copy = { ...obj };
// Function args
Math.max(...numbers);
Rest (...)
// Function parameters
function sum(...nums) { }
// Destructuring
const [first, ...rest] = arr;
const { name, ...details } = obj;
Key Points
- Spread: expands iterables
- Rest: collects into arrays
- Rest must be last parameter
- Both create shallow copies
- Later values overwrite earlier in objects