Spread & Rest in Depth

One syntax, two opposite jobs -- expanding values out and gathering them in.

Syntax[...iterable] { ...object } fn(...args) function f(...rest) {}

The same ... means opposite things depending on where it sits.

Spread -- expand outward

In array literals, object literals, and call arguments it unpacks an iterable or an object's own enumerable properties.

const merged = { ...defaults, ...overrides };  // later wins
const copy   = [...list];                       // shallow clone
Math.max(...numbers);                            // array to args

Rest -- gather inward

In a parameter list or a destructuring pattern it collects the leftovers into a real array or object.

function log(first, ...others) {}   // others is an array
const { id, ...rest } = record;      // rest is everything else

The catch

Both do a shallow copy. Nested objects are shared by reference, which is the number-one spread bug.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Collect all extra keyword arguments into a rest parameter object in a variadic logger function.
  • Spread a config override object into a defaults object to merge settings without mutation.
  • Spread an array of IDs into a SQL IN clause template string helper.

More examples

Rest parameters in a function

Collects all arguments after level into a rest array so any number of messages can be logged.

Example · js
function log(level, ...messages) {
  messages.forEach(m => console.log(`[${level}] ${m}`));
}
log("INFO", "Server started", "Listening on port 3000");

Spread to merge objects

Merges defaults and overrides into a new object; later spread keys overwrite earlier ones.

Example · js
const defaults = { timeout: 5000, retries: 3, debug: false };
const overrides = { retries: 5, debug: true };
const config = { ...defaults, ...overrides };
console.log(config);

Spread args from array

Spreads an array as individual positional arguments for functions that do not accept an array.

Example · js
function sum(a, b, c) { return a + b + c; }
const args = [1, 2, 3];
console.log(sum(...args)); // 6
console.log(Math.min(...[8, 2, 5, 1])); // 1

Discussion

  • Be the first to comment on this lesson.