Q14 of 40 · JavaScript
What is the difference between the spread operator and rest parameters?
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!