Skip to main content

Command Palette

Search for a command to run...

Spread vs Rest Operators in JavaScript

Updated
8 min read
Spread vs Rest Operators in JavaScript

What spread operator does

In JavaScript, the spread operator (...) is used to expand (spread out) elements of an array, object, or iterable into individual elements.

🔹 Basic Idea

👉 It “unpacks” values

let arr = [1, 2, 3];

console.log(...arr); // 1 2 3

🔹 Common Uses of Spread Operator

  1. Copying Arrays 📋

let arr1 = [1, 2, 3];

let arr2 = [...arr1];

console.log(arr2); // [1, 2, 3]

👉 Creates a shallow copy

2. Merging Arrays 🔗

let a = [1, 2];

let b = [3, 4];

let merged = [...a, ...b];

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

3. Adding Elements

let arr = [2, 3];

let newArr = [1, ...arr, 4];

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

4. Copying Objects 🧾

let obj1 = { name: "Aman" };

let obj2 = { ...obj1 };

console.log(obj2);

5. Merging Objects

let obj1 = { name: "Aman" };

let obj2 = { age: 20 };

let merged = { ...obj1, ...obj2 };

👉 If keys clash, last one wins

6. Updating Objects (Very Important ⭐)

let user = { name: "Aman", age: 20 };

let updated = { ...user, age: 21 };

👉 Used a lot in React

7. Passing Arguments to Functions

function sum(a, b, c) { return a + b + c; }

let nums = [1, 2, 3];

sum(...nums); // 6

8. Converting String to Array

let str = "hello";

let chars = [...str];

console.log(chars); // ["h", "e", "l", "l", "o"]

🔹 Important Concept ⚠️

👉 Shallow Copy

Spread does NOT deeply copy nested objects.

let obj1 = { a: 1, b: { c: 2 } };

let obj2 = { ...obj1 };

obj2.b.c = 100;

console.log(obj1.b.c); // 100

What rest operator does

The JavaScript rest operator (...) is used to collect multiple elements or properties into a single array or object. It is called the "rest" operator because it gathers the rest of the user-supplied values into a single container.

It is primarily used in two contexts: function parameters and destructuring assignments.

1. In Function Parameters

The most common use of the rest operator is in a function definition to allow the function to accept an indefinite number of arguments. These arguments are then bundled into a real JavaScript array, which can be easily iterated over or have array methods (like map(), filter(), reduce()) applied to it.

Key aspects:

  • Indefinite arguments: It enables functions to handle a variable number of inputs.

  • Always an array: The rest parameter is an instance of Array, unlike the older arguments object.

  • Must be the last parameter: The rest parameter must be the last one in a function's parameter list, otherwise, a SyntaxError is thrown.

  • Example:

  • function showDetails(name, age, ...otherInfo) {

  • console.log(Name: \({name}, Age: \){age});

  • console.log(Other Info: ${otherInfo});

  • } showDetails('John', 30, 'Developer', 'NYC', 'USA');

  • In this example, name gets 'John', age gets 30, and the ...otherInfo rest parameter collects all remaining arguments into the otherInfo array.

  • 2. In Destructuring Assignments

    The rest operator can also be used during array and object destructuring to gather the remaining items that were not explicitly assigned to other variables.

  • Array Destructuring: It collects the remaining elements into an array.

    const [first, second, ...rest] = [1, 2, 3, 4, 5];
    console.log(first);  // Output: 1
    console.log(second); // Output: 2
    console.log(rest);   // Output: [3, 4, 5]
    
  • Object Destructuring: It collects the remaining properties into a new object.

    const person = {
      name: 'Aish',
      age: 21,
      city: 'Hyderabad',
      country: 'India'
    };
    const { name, age, ...rest } = person;
    console.log(name); // Output: Aish
    console.log(age);  // Output: 21
    console.log(rest); // Output: { city: 'Hyderabad', country: 'India' }
    
  • In summary, while both the rest and spread operators use the same ... syntax, the rest operator gathers or condenses items into a single variable (array or object), while the spread operator expands or unpacks items from a collection.

Differences between spread and rest

In JavaScript, both spread (...) and rest (...) use the same syntax—but they do completely opposite jobs.

🔹 Core Difference

Feature Spread Operator Rest Operator
Purpose Expands values Collects values
Meaning Breaks things apart Packs things together

🔹 1. Spread Operator (Expand)

👉 Used to unpack elements

Example:

let arr = [1, 2, 3];
console.log(...arr); // 1 2 3

In arrays:

let a = [1, 2];
let b = [3, 4];

let merged = [...a, ...b]; // [1,2,3,4]

In objects:

let obj1 = { name: "Aman" };
let obj2 = { age: 20 };

let merged = { ...obj1, ...obj2 };

🔹 2. Rest Operator (Collect)

👉 Used to gather multiple values into one

Example (functions):

function sum(...nums) {
  return nums.reduce((a, b) => a + b);
}

sum(1, 2, 3); // nums = [1,2,3]

🔹 3. Rest in Destructuring

Arrays:

let [a, ...rest] = [1, 2, 3, 4];

console.log(a);    // 1
console.log(rest); // [2,3,4]

Objects:

let { name, ...others } = {
  name: "Aman",
  age: 20,
  city: "Delhi"
};

console.log(others); // { age:20, city:"Delhi" }

🔹 Key Differences

Point Spread Rest
Direction Expands Collects
Use case Copy, merge, pass values Function params, destructuring
Position Anywhere in literals Must be last element
Output Individual values Array/Object

🔹 Simple Analogy

  • Spread = “open the box and take things out”

  • Rest = “put remaining things into a box”

🔹 Common Mistake 🚫

function test(...a, b) {} // ❌ error

👉 Rest must be last parameter

🔹 Combined Example (Very Important)

function demo(a, b, ...rest) {
  console.log(a, b);   // first two
  console.log(rest);   // remaining
}

let arr = [1, 2, 3, 4];

demo(...arr);

👉 Here:

  • ...arr → spread

  • ...rest → rest

Using spread with arrays and objects

The JavaScript spread syntax (...) expands iterables (like arrays) into individual elements or object properties into key-value pairs. It is widely used for copying, merging, and immutable updates.

Using Spread with Arrays

The spread syntax allows you to quickly copy or combine arrays without using methods like concat() or slice().

  • Copying an array (shallow copy): Creates a new array with the elements of the original, so modifying the copy doesn't affect the original.

    const original = [1, 2, 3];
    const copy = [...original];
    console.log(copy); // Output: [1, 2, 3]
    
  • Combining/Merging arrays: Inserts the elements of one or more arrays into a new one.

    const numbersOne = [1, 2, 3];
    const numbersTwo = [4, 5, 6];
    const combined = [...numbersOne, ...numbersTwo];
    console.log(combined); // Output: [1, 2, 3, 4, 5, 6]
    
  • Adding elements: You can easily add elements to the beginning or end of an array while creating a new one.

    const numbers = [1, 2, 3];
    const newNumbers = [0, ...numbers, 4];
    console.log(newNumbers); // Output: [0, 1, 2, 3, 4]
    
  • Passing arguments to a function: Expands an array's elements as individual arguments for a function call.

    function sum(a, b, c) {
      return a + b + c;
    }
    const nums = [1, 2, 3];
    console.log(sum(...nums)); // Output: 6
    

Using Spread with Objects

The spread syntax for objects (introduced later than arrays) copies enumerable properties from one object to another within a new object literal. This is particularly useful for state management in libraries like React, where immutability is important.

  • Copying an object (shallow copy): Creates a new object with the properties of the original.

    const person = { name: "Alice", age: 30 };
    const updatedPerson = { ...person };
    console.log(updatedPerson); // Output: { name: "Alice", age: 30 }
    
  • Merging objects: Combines properties from multiple objects into a single new one. In case of duplicate keys, the value from the right-most object takes precedence.

    const car = { brand: 'Ford', model: 'Mustang', color: 'red' };
    const carMore = { type: 'car', year: 2021, color: 'yellow' };
    const myCar = { ...car, ...carMore };
    console.log(myCar); 
    // Output: { brand: 'Ford', model: 'Mustang', color: 'yellow', type: 'car', year: 2021 }
    

Updating properties immutably: Create a new object with all original properties and overwrite specific ones.

const values = { x: 10, y: 20, z: 30 };
const newValues = { ...values, x: 50 }; // Overwrites 'x'
console.log(newValues); // Output: { x: 50, y: 20, z: 30 }