JavaScript Spread and Rest Operators: An Essential Guide for Beginners
Tags: javascript, webdev, tutorial
Published: 2022-12-29 10:49:33


Two JavaScript operators with same syntax but totally different working.

## Spread
**Spread** operator(`...`)  is a tool in modern JavaScript that is used when working with arrays, objects, and function calls. Spread allows objects and iterables (arrays for now) to be unpacked.

Too techie? Spread helps us expand _iterables_ into individual elements.

### Spread with Arrays
Using spread with arrays, is something that you'll see almost every time. So focus!

```js
const tools = ['hammer', 'screwdriver']
const otherTools = ['wrench', 'saw']

const allTools = [...tools, ...otherTools]
console.log(allTools)

//Output : ['hammer', 'screwdriver', 'wrench', 'saw']
```
In the example above, we see that we can **unpack** elements from array into another array.
This is super useful in cases, where we want to achieve `immutability`, like in React Applications.

### Spread with Objects
Like arrays, spread is used to copy and update objects. This was earlier done using `Object.assign()`, but spread make it simple.

```js
const ogObject = { language: 'english', darkMode: false }
const newObject = {...ogObject}

console.log(newObject)
//Output: {language: 'english', darkMode: false}
```
Similar to arrays, this creates a shallow copy, and the nested objects inside (if there are any) will still be passed by reference.

Spread shines when we have to **add or modify properties** on an existing object **without mutating** it.
```js
const player = {
    id: 2,
    name: 'Abhi',
}

const updatedPlayer = { ...player, isLoggedIn: true }

console.log(updatedPlayer)
//Output: {id: 2, name: 'Abhi', isLoggedIn: true}
```

One Important concept to remember with spread and nested objects is, when copying object, remember to spread the nested objects as well. 
```js
const player = {
    id: 2,
    name: 'Abhi',
    team: { 
       name: 'Avengers',
       city: 'LA',
    }
}
```
If the player is now the leader of the team and you want to update that inside the `team` property, which itself is an object.
**Doing this is wrong**
```js
const updatedPlayer = { ...player, team: {position: 'captain'} }
```
This will result in 
```
updatedPlayer -> 
id: 2,
name: 'Abhi',  
team: { position: 'captain' }
```
See how the old fields are overwritten, to do it **without mutating** we have to 
```js
const updatedPlayer = { 
    ...player, //copy entire player Object
    team: { 
      ...player.team, //copy entire player.team Object
      position: 'captain',//and then update/add a property on top of old properties
    }
}
```

### Spread in Function Calls 

Let's define a simple function that take 3 parameters and adds them
```js
function addThree(a, b, c){
    return a + b + c ;
}
```
To pass the values individually to the function call, you can do this:
```js
addThree(2, 4, 6)
//output
//10👌
```
Suppose you have an array that has the values that you want to pass. You can do something like this:
```js
const nums = [2, 4, 5 ]
addThree(nums[0], nums[1], num[2])
```
But this is not very efficient. Instead, you can use the spread operator to spread the elements of the nums array as individual arguments to the addThree function: 
```js
addThree(...nums)
```
This allows us to pass the values individually, shortening our code and increasing its readability

**Note**: The spread operator creates a shallow copy of an array or object, meaning that any top-level properties will be cloned, but any nested objects or arrays will still be passed by reference. This is important to keep in mind when using the spread operator to make copies of objects that contain nested objects or arrays.

## Rest
The rest operator (...) is used to represent an indefinite number of arguments as an array. It is usually used in function definitions to allow the function to accept any number of arguments.


```js
function sum(...nums) {
  let result = 0;
  for (const num of nums) {
    result += num;
  }
  return result;
}

console.log(sum(1, 2, 3, 4));
// Output: 10
```
This was done earlier using the `arguments` variable, but it cannot be used with newer arrow functions and additionally `arguments` is not a true array so map and filter doesnt apply on it.

### Rest to destructure Arrays and Objects
**Destructuring Arrays with Rest**
Here's an example of using the rest operator to destructure an array:
```js
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...others] = numbers;

console.log(first);
// Output: 1
console.log(second);
// Output: 2
console.log(others);
// Output: [3, 4, 5]
```


**Destructuring Objects with Rest**
You can also use the rest operator to destructure objects. Here's an example:
```js
const person = {
  name: 'John',
  age: 30,
  occupation: 'developer',
  location: 'New York'
};

const { name, age, ...otherInfo } = person;

console.log(name);
// Output: 'John'
console.log(age);
// Output: 30
console.log(otherInfo);
// Output: { occupation: 'developer', location: 'New York' }
```
In the example above, the rest operator is used to assign the remaining properties of the `person` object to the `otherInfo` variable.


### **tl;dr**: 
While the **rest** operator collects an indefinite number of arguments into an array, the **spread** operator extracts elements from an array (or properties from an object) and expands them into individual elements or properties.

Be sure not to confuse function parameters and function arguments:

```js
function foo (...bar) {} // rest
foo(...baz) // spread
```

There's also rest in destructuring, which should not be confused with literal spreading:
```js
const { a, b, ...others } = { a:1, b:2, c:3, d:4, e:5 } // rest
const aToE = { a, b, ...others } // spread
```

Destructuring is used to create varibles from array items or object properties.
Spread syntax is used to unpack iterables such as arrays, objects, and function calls.

Overall, the spread and rest operators are useful tools for working with arrays, objects, and function arguments in JavaScript. They can help you write more concise and readable code. Visit MDN if you ever want to learn more

follow me on [twitter](https://twitter.com/abhi_exe) , [LinkedIn](https://www.linkedin.com/in/abhijitdotsharma/)