Spread & Rest Operators
Spread & Rest Operators
Section titled “Spread & Rest Operators”What it is
Section titled “What it is”The spread (...) operator expands iterables into individual elements. The rest operator (same syntax) collects multiple elements into an array. Introduced in ES6 (2015), they provide flexible ways to work with collections.
Before this feature
Section titled “Before this feature”Required verbose methods to copy, merge, or collect arguments:
// Copying arraysconst arr1 = [1, 2, 3];const arr2 = arr1.slice();
// Merging arraysconst combined = arr1.concat([4, 5, 6]);
// Function with variable argumentsfunction sum() { const args = Array.prototype.slice.call(arguments); return args.reduce((a, b) => a + b, 0);}
// Copying objects (shallow)const obj2 = Object.assign({}, obj1);After this feature
Section titled “After this feature”Spread and rest provide clean, intuitive syntax:
// SPREAD - expand elements
// Copy arrayconst arr1 = [1, 2, 3];const arr2 = [...arr1];
// Merge arraysconst combined = [...arr1, 4, 5, 6];const merged = [...arr1, ...arr2, ...arr3];
// Copy/merge objectsconst user = { name: "Alice", age: 25 };const updated = { ...user, city: "NYC" };const merged = { ...defaults, ...userSettings };
// Spread in function callsconst numbers = [1, 2, 3];Math.max(...numbers); // same as Math.max(1, 2, 3)
// REST - collect elements
// Function parametersfunction sum(...numbers) { return numbers.reduce((a, b) => a + b, 0);}sum(1, 2, 3, 4); // 10
// Destructuring arraysconst [first, second, ...rest] = [1, 2, 3, 4, 5];// rest = [3, 4, 5]
// Destructuring objectsconst { name, ...otherProps } = { name: "Alice", age: 25, city: "NYC"};// otherProps = { age: 25, city: "NYC" }Why this is better
Section titled “Why this is better”- Readable: Intent is immediately clear
- Flexible: Works with arrays, objects, function args
- Immutable patterns: Easy to create copies without mutation
- DRY: Reduces boilerplate code
- Type-safe: Works naturally with modern JS features
Key notes / edge cases
Section titled “Key notes / edge cases”- Spread creates shallow copies (nested objects still referenced)
- Rest parameter must be last in function parameters
- Can’t spread objects into arrays or vice versa (without conversion)
- Spread preserves order; later properties override earlier ones
- Can combine spread with other elements
// Shallow copy caveatconst original = { user: { name: "Alice" } };const copy = { ...original };copy.user.name = "Bob";console.log(original.user.name); // "Bob" (both reference same object!)
// Deep copy requires different approachconst deepCopy = JSON.parse(JSON.stringify(original));
// Override with spread (order matters!)const defaults = { color: "red", size: "M" };const custom = { size: "L" };const final = { ...defaults, ...custom };// { color: "red", size: "L" }
// Combine spread with literal elementsconst extended = [...arr1, "middle", ...arr2];Quick practice
Section titled “Quick practice”-
Merge two arrays
[1, 2]and[3, 4]using spreadAnswer
const merged = [...[1, 2], ...[3, 4]];// orconst arr1 = [1, 2], arr2 = [3, 4];const merged = [...arr1, ...arr2]; -
Create a function that accepts any number of arguments and returns their average
Answer
function average(...numbers) {return numbers.reduce((a, b) => a + b, 0) / numbers.length;} -
Add a property
verified: trueto an existing user object without mutating itAnswer
const updatedUser = { ...user, verified: true };