Technology · JavaScript

JavaScript Spread and Rest

Use spread operator for arrays and objects, rest parameters for flexible function arguments.

TL;DR
  1. 01Use ... to spread array or object elements into new contexts.
  2. 02Use rest parameters to collect arguments into an array.
  3. 03Spread and rest look the same but work in opposite directions.

Spread with Arrays

  • Use spread to expand array elements into a new array.
    const arr1 = [1, 2, 3];
    const arr2 = [4, 5, 6];
    const combined = [...arr1, ...arr2];
    // [1, 2, 3, 4, 5, 6]
  • Insert elements at specific positions using spread.
    const arr = [1, 2, 5];
    const updated = [1, 2, 3, 4, ...arr.slice(2)];
    // [1, 2, 3, 4, 5]
  • Copy an array without reference using spread.
    const original = [1, 2, 3];
    const copy = [...original];
    // Modifying copy doesn't affect original
  • Pass array elements as individual arguments to functions.
    const numbers = [1, 2, 3];
    Math.max(...numbers); // 3
  • Spread works with any iterable, including strings and Sets.
    const unique = [...new Set([1, 1, 2, 2, 3])];
    // [1, 2, 3]

Spread with Objects

  • Use spread to copy and merge object properties.
    const user = { name: "Alice", age: 30 };
    const updated = { ...user, age: 31 };
    // { name: "Alice", age: 31 }
  • Later properties override earlier ones when spreading.
    const base = { a: 1, b: 2 };
    const override = { ...base, b: 3 };
    // { a: 1, b: 3 }
  • Merge multiple objects using multiple spreads.
    const obj1 = { a: 1 };
    const obj2 = { b: 2 };
    const obj3 = { c: 3 };
    const merged = { ...obj1, ...obj2, ...obj3 };
  • Spread only copies top-level properties, not nested values.
    const original = { user: { name: "Alice" } };
    const copy = { ...original };
    // copy.user and original.user reference the same object
  • Add or remove properties using spread with destructuring.
    const { password, ...safeUser } = user;
    // password is removed, rest copied to safeUser

Rest Parameters

  • Use rest syntax to collect remaining function arguments into an array.
    function sum(...numbers) {
      return numbers.reduce((a, b) => a + b, 0);
    }
    sum(1, 2, 3, 4); // 10
  • Rest parameter must be the last parameter in the function.
    function greet(greeting, ...names) {
      console.log(`${greeting} ${names.join(", ")}`);
    }
    greet("Hello", "Alice", "Bob", "Charlie");
  • Use rest with destructuring to separate specific values.
    const [first, ...rest] = [1, 2, 3, 4];
    // first = 1, rest = [2, 3, 4]
  • Combine named parameters with rest for flexible APIs.
    function config(name, version, ...options) {
      // name and version are required, options are optional
    }
  • Rest gives you a real array so array methods work directly on it.
    function logAll(...messages) {
      messages.forEach(msg => console.log(msg));
      console.log('Total:', messages.length);
    }
    logAll('a', 'b', 'c');

Spread vs Rest

  • Spread expands elements, rest collects them.
    // Spread: expanding an array
    const arr = [1, 2, 3];
    const expanded = [...arr]; // Expands into individual elements
    
    // Rest: collecting arguments
    function collect(...args) {
      // Collects arguments into an array
    }
  • Spread is used in function calls and literals.
    Math.max(...[1, 2, 3]);     // Spread in call
    const arr = [1, ...rest];    // Spread in literal
    const obj = { ...user };     // Spread in literal
  • Rest is used in function parameters and destructuring.
    function fn(...args) { }     // Rest in parameters
    const [a, ...rest] = arr;    // Rest in destructuring
    const { x, ...rest } = obj;  // Rest in destructuring
  • Spread creates a shallow copy; rest collects into a new array or object.
    const original = [1, 2, 3];
    const copy = [...original];     // spread: new array, same values
    const [first, ...remaining] = original; // rest: collects into array
  • Use spread to pass variable-length data into fixed-arity functions.
    const args = [1, 5, 3, 9, 2];
    Math.min(...args); // 1 — spread turns array into individual args
    Math.max(...args); // 9

Common Patterns

  • Clone and update arrays without mutation.
    const items = [1, 2, 3];
    const updated = [...items, 4];
    const removed = items.filter(i => i !== 2);
  • Combine shallow cloning with merging.
    const defaults = { timeout: 5000, retries: 3 };
    const custom = { timeout: 10000 };
    const config = { ...defaults, ...custom };
  • Use rest in destructuring to handle extra values.
    const [head, ...tail] = [1, 2, 3, 4];
    // head = 1, tail = [2, 3, 4]
  • Spread into template literals with objects.
    const defaults = { a: 1, b: 2 };
    const custom = { b: 3, c: 4 };
    const final = { ...defaults, ...custom };

Tip: Use spread for shallow cloning and merging, but remember it only copies top-level properties — use structuredClone for deep clones.

Warning: Spread on objects only copies own properties, not inherited ones or non-enumerable properties from the prototype chain.

JavaScript Regular ExpressionsJavaScript Storage