Online Compiler logoOnline Compiler

JavaScript Spread & Rest Operator

Explore how the ES6 spread operator and rest syntax simplify working with arrays, objects, and function arguments.

What is the Spread Operator?

The spread operator (...) allows an iterable such as an array or string to be expanded in places where zero or more arguments or elements are expected. It's a concise syntax introduced in ES6 that makes cloning and merging easier.

Spread works with arrays, objects, and function calls. It 'spreads' individual elements or properties into a new container.

Basic Array Spread

const colors = ['red', 'green'];
const moreColors = [...colors, 'blue'];
console.log(moreColors); // ['red', 'green', 'blue']

Use spread to expand an existing array into a new one, allowing easy insertion of elements.

Spread with Arrays

Spread makes it simple to copy arrays, concatenate them, or convert iterable objects into arrays.

Clone an Array

const original = [1, 2, 3];
const clone = [...original];
clone.push(4);
console.log(original); // [1, 2, 3]
console.log(clone);    // [1, 2, 3, 4]

Spreading into a new array creates a shallow copy without linking to the original.

Merge Arrays

const a = [1, 2];
const b = [3, 4];
const merged = [...a, ...b];
console.log(merged); // [1, 2, 3, 4]

Combine multiple arrays cleanly without using concat().

Convert Iterable to Array

const str = 'hello';
const chars = [...str];
console.log(chars); // ['h','e','l','l','o']

Spread can convert strings or other iterables into arrays.

Spread with Objects

Since ES2018, objects support spread syntax. You can clone objects, merge them, or override properties using spread.

Clone an Object

const user = { name: 'Alice', age: 25 };
const clone = { ...user };
clone.age = 26;
console.log(user.age); // 25
console.log(clone.age); // 26

Object spread creates a shallow copy of the original object.

Merge/Object Override

const defaults = { theme: 'light', lang: 'en' };
const prefs = { lang: 'es' };
const config = { ...defaults, ...prefs };
console.log(config); // { theme: 'light', lang: 'es' }

Later spreads override earlier properties, making it easy to apply defaults.

Add or Remove Properties

const base = { a: 1, b: 2 };
const extended = { ...base, c: 3 };
const withoutB = (({ b, ...rest }) => rest)(base);
console.log(extended); // { a: 1, b: 2, c: 3 }
console.log(withoutB); // { a: 1 }

Spread and destructuring/rest can add or omit properties in new object creations.

Rest Parameters

Rest syntax also uses "..." but in function parameters or destructuring patterns to collect multiple values into a single array or object.

Function with Rest Parameters

function multiply(factor, ...numbers) {
  return numbers.map(n => n * factor);
}

console.log(multiply(2, 1, 2, 3)); // [2, 4, 6]

Rest parameters gather the remaining arguments into an array. Only the last parameter may be a rest parameter.

Array Destructuring with Rest

const [first, ...rest] = [10, 20, 30, 40];
console.log(first); // 10
console.log(rest);  // [20, 30, 40]

Rest collects remaining array elements during destructuring.

Object Destructuring with Rest

const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(a);      // 1
console.log(others); // { b: 2, c: 3 }

Rest in object destructuring gathers remaining properties into a new object.

Spread vs Rest

Though they look identical, spread 'expands' values while rest 'collects' them. Context determines which behavior you get. In arrays/objects literals use spread, in function parameters or destructuring use rest.

Common Mistakes and Gotchas

Shallow Copy Only

const nested = [{ x: 1 }];
const copy = [...nested];
copy[0].x = 2;
console.log(nested[0].x); // 2  (changed!)

Spread only performs a shallow copy; nested objects are still shared. Use structuredClone or deep copy when needed.

Using Rest Not as Last Parameter

function test(...args, extra) {
  // SyntaxError: Rest parameter must be last
}

Rest parameter must be the last parameter in a function definition.

Forgetting to Use Spread When Cloning

const a = [1,2,3];
const b = a; // reference copy
b.push(4);
console.log(a); // [1,2,3,4]  // mutated!

Assigning directly copies by reference; use [...a] to clone.

FAQ

Related Topics

Key Takeaways

  • Spread expands iterable values into new arrays or objects
  • Rest collects multiple elements into a single array or object
  • Both use the same ... syntax but behave differently based on context
  • Spread creates shallow copies; nested data is still referenced
  • Rest parameters must appear last in a function signature
  • Use spread for cloning/merging and rest for function arguments or destructuring