# Spread vs Rest Operators in JavaScript

Despite both using the same three-dot syntax (`...`), the **Spread** and **Rest** operators perform opposite operations in JavaScript:

*   **Spread (**`...`**)** **expands** an iterable (like an array or object) into individual elements.
    
*   **Rest (**`...`**)** **collects** multiple individual elements into a single array structure.
    

## 1\. Visualizing Spread vs. Rest

The easiest way to remember the distinction is **Expanding vs. Collecting**:

```ruby
SPREAD (Expanding):
   [1, 2, 3]  ─── Spread (...) ───>  1, 2, 3
   (One container into many standalone values)

REST (Collecting):
   1, 2, 3, 4  ─── Rest (...) ───>  [1, 2, 3, 4]
   (Many standalone values gathered into one container)
```

## 2\. The Spread Operator (`...`)

The Spread operator unrolls or unpacks elements from an array or object. Think of it like taking items out of a box and laying them out individually.

### Spread with Arrays

#### 1\. Combining / Concatenating Arrays

```javascript
const fruits = ["apple", "banana"];
const vegetables = ["carrot", "spinach"];

// Unpacks elements into a new array
const food = [...fruits, ...vegetables];
console.log(food); // ["apple", "banana", "carrot", "spinach"]
```

2\. Shallow Copying an Array

```javascript
const original = [1, 2, 3];
const copy = [...original]; // Creates a brand new array reference

copy.push(4);
console.log(original); // [1, 2, 3] (unchanged)
console.log(copy);     // [1, 2, 3, 4]
```

### Spread with Objects

You can spread object key-value pairs into a new object to copy or merge properties effortlessly.

```javascript
const user = { name: "Ananya", age: 21 };
const location = { city: "Kolkata", country: "India" };

// Merge objects (and override/add properties easily)
const updatedUser = {
  ...user,
  ...location,
  age: 22 // Overrides age from user object
};

console.log(updatedUser);
// Output: { name: 'Ananya', age: 22, city: 'Kolkata', country: 'India' }
```

## 3\. The Rest Operator (`...`)

The Rest operator gathers "the rest" of user-supplied arguments or elements into a consolidated array. It is primarily used in **function parameters** and **destructuring**.

**1\. Rest in Function Parameters**

When building functions that accept an unknown number of arguments, the Rest parameter collects them all into a standard JavaScript array.

```javascript
// Collects all arguments into an array named 'numbers'
function sumAll(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sumAll(5, 10));         // 15
console.log(sumAll(1, 2, 3, 4, 5)); // 15
```

> ⚠️ **Rule:** The Rest parameter **must always be the last parameter** in a function definition!

```javascript
// Valid:
function setupUser(id, ...details) {} 

// Invalid (SyntaxError):
// function setupUser(...details, id) {}
```

**2\. Rest in Array Destructuring**

```javascript
const scores = [98, 85, 72, 60, 45];

// Unpack first two items, gather the rest into an array
const [first, second, ...remainingScores] = scores;

console.log(first);           // 98
console.log(second);          // 85
console.log(remainingScores); // [72, 60, 45]
```

**3\. Rest in Object Destructuring**

```javascript
const student = {
  id: 101,
  name: "Rahul",
  grade: "A",
  city: "Kolkata"
};

// Extract 'name', collect all other properties into 'otherInfo'
const { name, ...otherInfo } = student;

console.log(name);      // "Rahul"
console.log(otherInfo); // { id: 101, grade: 'A', city: 'Kolkata' }
```

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Feature</strong></p></td><td colspan="1" rowspan="1"><p><strong>Spread Operator (...)</strong></p></td><td colspan="1" rowspan="1"><p><strong>Rest Operator (...)</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Core Function</strong></p></td><td colspan="1" rowspan="1"><p><strong>Expands</strong> elements apart</p></td><td colspan="1" rowspan="1"><p><strong>Gathers</strong> standalone elements together</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Where it appears</strong></p></td><td colspan="1" rowspan="1"><p>On the <strong>right</strong> side of assignments or inside array/object literals and function calls</p></td><td colspan="1" rowspan="1"><p>On the <strong>left</strong> side of assignments (destructuring) or in function <strong>parameters</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Target Use Case</strong></p></td><td colspan="1" rowspan="1"><p>Merging arrays/objects, passing array elements to functions</p></td><td colspan="1" rowspan="1"><p>Handling variable function arguments, extracting specific properties</p></td></tr></tbody></table>

### Exampile

Pattern 1: Passing Array Elements as Function Arguments

```javascript
const numbers = [45, 12, 89, 3];

// Math.max expects individual arguments: Math.max(45, 12, 89, 3)
const maxNumber = Math.max(...numbers); // Spread expands array
console.log(maxNumber); // 89
```

Pattern 2: Immutably Removing a Property from an Object

```javascript
const product = {
  id: "P100",
  title: "Wireless Mouse",
  price: 25,
  internalCode: "SECRET123"
};

// Remove 'internalCode' without altering original product object
const { internalCode, ...cleanProduct } = product;

console.log(cleanProduct); // { id: 'P100', title: 'Wireless Mouse', price: 25 }
```
