JS CodeLab

JavaScript Spread and Rest Operators (...): Complete Guide

By JS CodeLab Engineering Team•Last updated: October 12, 2026•5 min read

Direct Answer & Key Concept

The three dots (...) in JavaScript represent either the spread operator or rest parameters depending on context. Spread unpacks elements into an iterable, while rest condenses multiple elements into a single array.

Runnable Code SnippetRun in Playground
// Spread and Rest in Action
const teamA = ["Alice", "Bob"];
const teamB = ["Charlie", "Diana"];

// Spread: Merge arrays
const allMembers = [...teamA, ...teamB];
console.log("All members:", allMembers); // ["Alice", "Bob", "Charlie", "Diana"]

// Rest: Gather function arguments
const logLeaderAndMembers = (leader, ...members) => {
  console.log("Leader:", leader);
  console.log("Team:", members);
};

logLeaderAndMembers(...allMembers);
// Leader: Alice
// Team: ["Bob", "Charlie", "Diana"]

What are the Spread and Rest operators in JavaScript?

The three consecutive dots (...) syntax in JavaScript serves two complementary purposes governed by where it appears in your code:

  1. Spread Operator: Unpacks an array or object into individual elements. Used in array literals, object literals, and function invocation arguments.
  2. Rest Parameters: Collects multiple individual elements into a single array. Used in function parameter declarations and destructuring patterns.

When to use the Spread Operator

1. Shallow Cloning Objects and Arrays

Spread creates a clean shallow copy without mutating the original reference:

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

console.log("Original:", original); // [1, 2, 3] (Untouched)
console.log("Clone:", clone);       // [1, 2, 3, 4]

2. Merging Arrays and Objects

const baseConfig = { timeout: 5000, debug: false };
const envConfig = { debug: true, env: "production" };

// Latter properties override earlier ones
const finalConfig = { ...baseConfig, ...envConfig, port: 8080 };
console.log(finalConfig);
// { timeout: 5000, debug: true, env: "production", port: 8080 }

When to use Rest Parameters

Rest parameters allow functions to accept variable numbers of arguments cleanly as a real Array instance:

function calculateScore(bonus, ...points) {
  const sum = points.reduce((acc, curr) => acc + curr, 0);
  return sum + bonus;
}

console.log(calculateScore(10, 5, 15, 20)); // 50

Common Mistakes with Spread and Rest

  1. Assuming spread creates a deep clone: Spread copies only top-level properties (shallow copy). Nested objects and arrays still share memory references. Use structuredClone() for true deep cloning.
  2. Placing rest parameters before other parameters: Rest parameters must always be the final parameter in a function signature: function test(...rest, last) throws a SyntaxError: Rest parameter must be last formal parameter.

Frequently Asked Questions About JavaScript Spread and Rest Operators (...): Complete

Does the spread operator create a deep copy or shallow copy?

The spread operator creates a shallow copy. It duplicates top-level primitive values, but any nested objects or arrays retain their original memory references.

Can you place a rest parameter at the beginning of a function signature?

No. A rest parameter must always be the last parameter in the function declaration. Placing anything after a rest parameter causes a SyntaxError.

How do you deep clone an object in modern JavaScript without spread limitations?

Use the browser-native structuredClone() API (e.g., const deepCopy = structuredClone(originalObject);), which safely copies complex nested objects, arrays, and dates.

Related Runnable JavaScript Examples

Ready to test what you learned?

The best way to solidify your JavaScript skills is by writing and running code. Open our free online compiler and test your scripts with real-time console feedback.

Open JavaScript Compiler