Spread and Rest operator in JavaScript
Published: 2021-08-30 17:29:37

These (...) three dots are called the spread or rest operator depending upon the task it is performing. 

#Spread operator
In simple terms, it converts an array into its individual values. 
```js
const numbers = [1, 2, 3, 4, 5];

console.log(numbers);  // output: [1, 2, 3, 4, 5]

//with spread operator
console.log(...numbers); // output: 1, 2, 3, 4, 5
```
It can also be used to convert strings into individual characters or objects into individual key-value pairs.

###In function calls
```js
Math.max(5, 6, 7);       //result: 7

const nums = [1, 2, 3];
Math.max(nums);         //result: NaN
Math.max(...nums);      //result: 3
```
Here, `Math.max` function returns the maximum value. When we have to pass the values in an array, we cannot pass it directly as the function is not expecting an array as the argument. So, we have to pass it using spread operator `...nums`.

###Concatenate arrays
```js
const numbers1 = [0, 1, 2];
const numbers2 = [3, 4, 6];

const allNumbers = [...numbers1, ...numbers2];
console.log(allNumbers);   //output: [0, 1, 2, 3, 4, 6]
```
The spread operator makes the concatenation of arrays easier.  


###Add elements in an array
```js
const moreNumbers = [9, ...numbers1, 11, ...[5]];
console.log(moreNumbers);  //output: [9, 0, 1, 2, 11, 5]
```
1. A better way to push elements in an array, as it does not modify the existing array like the push method.
2. Add elements at the start of the array, without modifying the existing array.

###Copying arrays and objects
In JavaScript, arrays and objects are passed by reference. So, whenever a variable defined as an array or object is assigned to another variable. Then, both of those variables point to the same array or object. That means if one array is modified both get modified because they are pointing to the same array.

```js
let letters = ["a", "b", "c"];

let abc = letters;

abc[0] = "z";

console.log(letters);  //output: ["z", "b", "c"]
console.log(abc);      //output: ["z", "b", "c"]
```
In the above example, the `letters` array is defined and then it is assigned to the `abc` array. So, when `abc` array is modified `letters` array gets modified too.

```js
let letters = ["a", "b", "c"];

let abc = ...letters;

abc[0] = "z";

console.log(letters);  //output: ["a", "b", "c"]
console.log(abc);      //output: ["z", "b", "c"]
```
Creating a copy of an array gets easier with the spread operator. Using `let abc = ...letters` makes a copy of an array instead of passing reference of the same array. The same goes for objects in JavaScript.

###Merging objects
```js
const obj1 = {
  red: "apple",
  green: "grapes",
};

const obj2 = {
  yellow: "banana",
};

const fruits = { ...obj1, ...obj2 };
console.log(fruits);
//output:{ red: 'apple', green: 'grapes', yellow: 'banana' }
```
Like concatenating arrays, the spread operator can also be used to merge objects. 


#Rest operator

Rest operator is used while defining functions. It does the exact opposite of spread. It takes the values passed as arguments in a function and converts them into an array. This is not the same as `arguments` object in JavaScript. Methods like `forEach()`, `reduce()`, `map()` do not work with `arguments` object.

```js
function add(...args) {
  let sum = 0;

  args.forEach(value => {
    sum += value;
  });

  return sum;
}

console.log(add(2, 3, 4, 5, 6)); //output: 20
```
In the above example, the arguments passed while calling the add function get converted into an array because of the rest operator used while defining the add function. Then we loop through the `args` array and calculate the sum.

```js
function print(first, second, ...rest) {
  console.log(first);
  console.log(second);
  console.log(rest);
}

print("q", "w", "e", "r", "t", "y");
```
Output:
![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnhu5vqrui0vad0ybew2.png)
Given above is another way of using the rest operator, the first two arguments that are `'q'` and `'w'` are assigned to the variables `first` and `second` respectively. And the remaining arguments form an array defined as `rest`.

#####Incorrect Usage
```js
function doSomething(first, ...middle, last) {
  // do something
}
```

When I first learned about the rest operator, I used it incorrectly and couldn't figure out the error. The above code sample is a mistake a lot of beginners make. The rest parameter must be the last in the function definition.

**Thanks for reading.**