← All concepts
Data Structures, Operators & Strings

Spread and Rest

The same ... syntax expands a value out in one context and gathers values together in the other.

Definition

Spread and rest share the `...` syntax, but they do opposite jobs depending on where they appear. Spread expands an iterable, like an array, or an object's own properties, into the surrounding context: `[...a, ...b]` unpacks every element of `a` and `b` into a new array, and `{ ...obj, extra: 1 }` copies every property of `obj` into a new object. Because it builds a new array or object, spread makes a shallow copy: top-level values are duplicated, but nested objects or arrays are still shared by reference with the original. Rest does the reverse: it gathers the remaining items into a single array. In a destructuring pattern, `const [first, ...rest] = arr` collects everything after `first`. In a function signature, `function sum(...nums)` collects every argument the function was called with. A rest element must be the last item in its pattern or parameter list, since it claims everything left over.

Examples

const a = [1, 2];
const b = [3, 4];
const combined = [...a, ...b];
// [1, 2, 3, 4]

Spread unpacks both arrays' elements into a brand new array; a and b are left untouched.

const base = { role: "user" };
const admin = { ...base, role: "admin" };
// { role: "admin" }, base is still { role: "user" }

Spreading an object copies its own properties first, so a later key with the same name overrides the spread value.

function sum(first, ...rest) {
  return first + rest.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10

Rest collects every argument after the first one into a real array, which is why reduce works on it directly.

Common mistakes

  • Assuming spread makes a deep copy; it only copies the top level, so nested objects and arrays are still shared by reference.
  • Placing a rest parameter anywhere but last, or trying to use more than one in a single pattern; rest must be the final item.
  • Spreading an object and then setting the same key again, and being surprised the later key wins instead of the spread value.

Key takeaways

  • Spread expands an array or object's own values into a new one; rest gathers leftover values into an array.
  • Spread makes a shallow copy; nested objects and arrays remain shared with the original.
  • A rest element must come last in a destructuring pattern or parameter list.
Check your understanding

`const base = { role: "user" }; const admin = { ...base, role: "admin" };` What is `admin.role`?

Where you see this

  • Merging or cloning objects and arrays without mutating the originals, like spreading previous state in a reducer.
  • Writing a function that accepts any number of arguments, such as a custom Math.max or a logging helper.
  • Passing an array of values as individual arguments to a function, like Math.max(...scores).
  • Splitting an array into a head element and the remaining tail with a rest pattern.

Practice this

Further reading

Previous
Destructuring
Next
Optional Chaining and Nullish Coalescing