Spread & Rest

  • This lesson explains spread and rest operators with practical examples.
  • Introduction to Spread, Rest & Optional Chaining

    Modern JavaScript (ES6+) provides powerful operators that help developers write:

    • Cleaner code

    • More readable logic

    • Safer DOM and object access

    In this lesson, we will learn:

    1. Spread Operator (...)

    2. Rest Operator (...)

    3. Optional Chaining (?.)

    Even though these features are language-level concepts, they are extremely useful in DOM manipulation, functions, and data handling.

    Spread & Rest Operators

    What is the Spread Operator ?

    The spread operator (...) is used to expand or unpack values from:

    • Arrays

    • Objects

    • Strings

    In simple words:

    Spread takes a group of values and spreads them out.

    Syntax of Spread Operator

    ...iterable

Copy Arrays Using Spread Operator

Creates a shallow copy of an array using spread syntax

let numbers = [1, 2, 3];

let copyNumbers = [...numbers];

console.log(copyNumbers);
  • This creates a new array, not a reference.

Merge Arrays Using Spread Operator

Combines multiple arrays into a single array using spread syntax

let arr1 = [1, 2];
let arr2 = [3, 4];

let merged = [...arr1, ...arr2];

console.log(merged);
  • Why Spread is Better Than Traditional Methods

    Traditional way:

    let arr2 = arr1;

    Problem:

    • Changes in arr2 affect arr1

    Spread creates a shallow copy, avoiding this issue.

    Spread Operator with Objects

Copy and Merge Objects Using Spread Operator

Uses spread syntax to duplicate and combine object properties

// Copy object
let user = { name: "Rahul", age: 25 };

let newUser = { ...user };

// Merge objects
let obj1 = { a: 1 };
let obj2 = { b: 2 };

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

console.log(newUser, combined);
  • Spread Operator in DOM Manipulation

Convert NodeList to Array Using Spread Operator

Uses spread syntax to transform a NodeList into a real array

let items = document.querySelectorAll("li");

let itemsArray = [...items];

console.log(itemsArray); // real array
  • Now array methods like map() and filter() can be used.

Convert String to Array Using Spread Operator

Splits a string into individual characters as an array

let text = "JS";

let chars = [...text];

console.log(chars); // ["J", "S"]
  • What is the Rest Operator ?

    The rest operator (...) is used to collect multiple values into a single variable.

    In simple words:

    Rest gathers values into a group.

    Syntax of Rest Operator

    function example(...args) {

      // args is an array

    }

    Rest Operator in Functions

Handle Multiple Arguments Using Rest Operator

Collects multiple function arguments into a single array

function sum(...numbers) {
  let total = 0;

  for (let num of numbers) {
    total += num;
  }

  return total;
}

console.log(sum(10, 20, 30)); // 60
  • Rest Operator with Parameters

Use Rest Operator with Function Parameters

Captures remaining arguments after fixed parameters into an array

function show(a, b, ...rest) {
  console.log(a);     // 1
  console.log(b);     // 2
  console.log(rest);  // [3, 4, 5]
}

show(1, 2, 3, 4, 5);
  • Rest Operator in Destructuring

Use Rest Operator in Destructuring

Extracts remaining elements or properties into a separate variable

// Array destructuring
let [first, ...remaining] = [10, 20, 30, 40];

console.log(first);      // 10
console.log(remaining);  // [20, 30, 40]

// Object destructuring
let { name, ...details } = {
  name: "Amit",
  age: 22,
  city: "Delhi"
};

console.log(name);    // Amit
console.log(details); // { age: 22, city: "Delhi" }
  • Spread vs Rest
    FeatureSpreadRest
    PurposeExpands valuesCollects values
    UsageRight sideFunction parameters
    MeaningUnpackPack
    Symbol......
  • Same syntax, different use case.

    Optional Chaining (?.)

    What is Optional Chaining ?

    Optional chaining (?.) allows safe access to:

    • Object properties

    • Nested objects

    • Methods

    Without throwing errors if a value is null or undefined.

Error When Accessing Nested Properties Without Checks

Shows how accessing undefined nested properties causes runtime errors

let user = {};

// Error: Cannot read properties of undefined
console.log(user.profile.name);
  • This causes a runtime error because profile does not exist.

Safely Access Nested Properties Using Optional Chaining

Prevents errors by returning undefined if a property does not exist

let user = {};

// Safe access using optional chaining
console.log(user.profile?.name); // undefined
  • No error occurs.

Use Optional Chaining with Nested Objects

Safely accesses nested properties without causing errors if they are missing

let student = {
  name: "Ravi",
  address: {
    city: "Mumbai"
  }
};

console.log(student.address?.city);     // Mumbai
console.log(student.address?.pincode);  // undefined
  • Optional Chaining with Functions

Safely Call Functions Using Optional Chaining

Prevents errors when calling functions that may not exist

let obj = {
  greet() {
    console.log("Hello");
  }
};

// Function exists
obj.greet?.(); // Hello

// Function does not exist (no error)
obj.sayHi?.(); // undefined
  • Optional Chaining with Arrays

Safely Access Array Elements Using Optional Chaining

Prevents errors when accessing properties of undefined array elements

let users = [];

// Safe access
console.log(users[0]?.name); // undefined
  • Optional Chaining in DOM Manipulation

Safe Event Binding Using Optional Chaining in DOM

Prevents errors if the DOM element does not exist before adding event listener

// Safe DOM access
document.getElementById("btn")?.addEventListener("click", () => {
  console.log("Clicked");
});
  • If the element does not exist, no error occurs.

    When to Use Optional Chaining

    • API responses

    • Dynamic DOM elements

    • Deeply nested objects

    • User input data

    When Not to Overuse Optional Chaining

    • When value is guaranteed to exist

    • When errors should be handled explicitly

    Common Beginner Mistakes

    • Confusing spread with rest

    • Overusing optional chaining

    • Expecting deep cloning using spread

    • Using rest outside function parameters

      Best Practices

      • Use spread for copying and merging

      • Use rest for flexible functions

      • Use optional chaining for safety

      • Keep code readable

      • Avoid unnecessary nesting

      Use Cases

      • Handling API data safely

      • Working with dynamic DOM elements

      • Creating utility functions

      • Managing application state

      • Writing reusable components