Q14 of 40 · JavaScript

What is the difference between the spread operator and rest parameters?

JavaScriptJuniorjavascriptspreadrestes6arraysobjects

Short answer

Short answer: Both use `...` syntax but in opposite directions. Spread expands an iterable or object into individual elements at a call site or literal. Rest collects remaining arguments or destructuring elements into an array in a function definition or destructuring pattern.

Detail

The ... syntax has two opposite meanings depending on where it appears.

Spread is used in:

  • Array literals: [...arr1, ...arr2] — shallow-merges arrays
  • Object literals: { ...obj1, ...obj2 } — shallow-merges objects (later keys win)
  • Function calls: Math.max(...numbers) — expands array into individual arguments

Rest is used in:

  • Function parameters: function fn(a, b, ...rest) — collects remaining args into array
  • Destructuring: const [head, ...tail] = arr — collects remaining elements

Shallow merge warning: Object spread does a shallow merge. Nested objects are copied by reference, not cloned. Mutating a nested property after spreading affects both the original and the copy.

In test automation: Spread merges Playwright fixture options, extends base config objects, and clones flat test data. Rest parameters appear in wrapper functions that accept variable arguments.

// EXAMPLE

// Spread — expand
const a = [1, 2], b = [3, 4];
const merged = [...a, ...b];           // [1, 2, 3, 4]

const base = { timeout: 5000 };
const extended = { ...base, retries: 3 }; // {timeout:5000, retries:3}

Math.max(...[10, 3, 7]);               // 10

// Rest — collect
function sum(first, ...rest) {
  return rest.reduce((acc, n) => acc + n, first);
}
sum(1, 2, 3, 4); // 10

// Rest in destructuring
const [head, ...tail] = [10, 20, 30];
// head=10, tail=[20,30]

// Shallow merge caveat
const orig = { nested: { x: 1 } };
const copy = { ...orig };
copy.nested.x = 99;
console.log(orig.nested.x); // 99 — same reference!

// WHAT INTERVIEWERS LOOK FOR

Clear differentiation between spread (expand) and rest (collect) by context. Awareness of shallow merge semantics for object spread. Bonus: connecting spread to Playwright config patterns.

// COMMON PITFALL

Thinking spread performs a deep clone — it does not. `const copy = { ...original }` only copies top-level properties; nested objects are still shared references.