# ES6 Rest and Spread Operators

The ES6 (ECMAScript 2015) introduced two powerful operators: the rest operator (`...`) and the spread operator (`...`). While they look identical, they serve different purposes depending on the context in which they are used.

## Rest Operator

#### Definition

The rest operator allows you to represent an indefinite number of arguments as an array. It simplifies the handling of function parameters and can be used to capture all remaining elements in an array or function arguments.

### **Rest Operator Use Cases:**

#### 1\. Summing Arguments

Using the rest operator, you can simplify the process of summing an indefinite number of arguments.

**ES6 Example:**

```javascript
function sum(...args) {
  return args.reduce((acc, curr) => acc + curr, 0);
}

console.log(sum(1, 2, 3, 4)); // Output: 10
console.log(sum(5, 10, 15));  // Output: 30
```

**ES5 Equivalent:**

```javascript
function sum() {
  var args = Array.prototype.slice.call(arguments);
  return args.reduce(function(acc, curr) {
    return acc + curr;
  }, 0);
}

console.log(sum(1, 2, 3, 4)); // Output: 10
console.log(sum(5, 10, 15));  // Output: 30
```

#### 2\. Array Destructuring

The rest operator can also be used in array destructuring to collect the remaining elements into an array.

```javascript
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]
```

## Spread Operator

#### Definition

The spread operator (`...`) can take an iterable (like an array or a string) and expand its elements so that they are treated as individual arguments or elements in certain contexts. This expansion happens in places where multiple arguments or elements are expected, such as in function calls, array literals, or object literals:

#### 1\. Function Calls

In function calls, the spread operator allows the elements of an array to be passed as separate arguments to a function.

```javascript
const numbers = [1, 2, 3];

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

console.log(add(...numbers)); // Output: 6
```

Here, `...numbers` spreads the array `[1, 2, 3]` into individual arguments `1`, `2`, and `3` for the `add` function.

#### 2\. Array Literals

In array literals, the spread operator allows the elements of an iterable to be included as individual elements in a new array.

```javascript
const array1 = [1, 2, 3];
const array2 = [...array1, 4, 5, 6];

console.log(array2); // Output: [1, 2, 3, 4, 5, 6]
```

Here, `...array1` spreads the elements `1`, `2`, and `3` into the new array `array2`.

#### 3\. Object Literals

In object literals, the spread operator allows the properties of an iterable (typically an object) to be included as properties in a new object.

```javascript
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3, d: 4 };

console.log(obj2); // Output: { a: 1, b: 2, c: 3, d: 4 }
```

Here, `...obj1` spreads the properties `a: 1` and `b: 2` into the new object `obj2`.

### **Spread Operator Use Cases:**

#### 1\. Concatenation of Two Arrays

Using the spread operator, you can easily concatenate arrays.

```javascript
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const combinedArray = [...array1, ...array2];

console.log(combinedArray); // Output: [1, 2, 3, 4, 5, 6]
```

#### 2\. Splitting a String

The spread operator can also be used to split a string into individual characters.

```javascript
const str = "hello";
const chars = [...str];

console.log(chars); // Output: ['h', 'e', 'l', 'l', 'o']
```

#### 3\. Copying Arrays

The spread operator makes it simple to create a shallow copy of an array.

```javascript
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];

console.log(copiedArray); // Output: [1, 2, 3]
```

#### 4\. Merging Objects

The spread operator can also be used to merge objects.

```javascript
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const mergedObj = { ...obj1, ...obj2 };

console.log(mergedObj); // Output: { a: 1, b: 2, c: 3, d: 4 }
```

### Iterables

The spread operator works on any iterable, not just arrays. This includes strings, sets, and even custom iterables.

**Example with Sets:**

```javascript
const set = new Set([1, 2, 3]);
const arrayFromSet = [...set];

console.log(arrayFromSet); // Output: [1, 2, 3]
```

### Summary

* **Rest Operator (**`...args`): Used in function parameters to gather all remaining arguments into an array.
    
* **Spread Operator (**`...array`): Used in function calls, array literals, or object literals to spread elements or properties of an iterable (like an array or string) into a list of arguments or elements.
    
* **Use Cases**: Summing arguments, array destructuring, concatenating arrays, splitting strings, copying arrays, and merging objects.
    
* **Iterables**: The spread operator works on any iterable object, including arrays, strings, sets, and more.
    

These operators provide a concise and readable way to handle collections of data, making JavaScript code cleaner and easier to manage.
