Skip to content

Spread & Rest Operators

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.

Required verbose methods to copy, merge, or collect arguments:

// Copying arrays
const arr1 = [1, 2, 3];
const arr2 = arr1.slice();
// Merging arrays
const combined = arr1.concat([4, 5, 6]);
// Function with variable arguments
function sum() {
const args = Array.prototype.slice.call(arguments);
return args.reduce((a, b) => a + b, 0);
}
// Copying objects (shallow)
const obj2 = Object.assign({}, obj1);

Spread and rest provide clean, intuitive syntax:

// SPREAD - expand elements
// Copy array
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
// Merge arrays
const combined = [...arr1, 4, 5, 6];
const merged = [...arr1, ...arr2, ...arr3];
// Copy/merge objects
const user = { name: "Alice", age: 25 };
const updated = { ...user, city: "NYC" };
const merged = { ...defaults, ...userSettings };
// Spread in function calls
const numbers = [1, 2, 3];
Math.max(...numbers); // same as Math.max(1, 2, 3)
// REST - collect elements
// Function parameters
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10
// Destructuring arrays
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// rest = [3, 4, 5]
// Destructuring objects
const { name, ...otherProps } = {
name: "Alice",
age: 25,
city: "NYC"
};
// otherProps = { age: 25, city: "NYC" }
  • 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
  • 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 caveat
const 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 approach
const 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 elements
const extended = [...arr1, "middle", ...arr2];
  1. Merge two arrays [1, 2] and [3, 4] using spread

    Answer
    const merged = [...[1, 2], ...[3, 4]];
    // or
    const arr1 = [1, 2], arr2 = [3, 4];
    const merged = [...arr1, ...arr2];
  2. 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;
    }
  3. Add a property verified: true to an existing user object without mutating it

    Answer
    const updatedUser = { ...user, verified: true };