Destructuring arrays and objects 
Tags: javascript, typescript, webdev
Published: 2023-02-22 18:32:23

### Destructuring arrays and objects

Objects and arrays are data structures enabling us to store data in structured way. There are often cases when we don't need to use whole object/array but only its single elements. That's the best use case to try destructuring.

### Destructuring arrays

To assign value from array to specific variable, before ES6, we had to define each variable separately:

```javascript
const zoo = [🐙, 🦫, 🦭]
const octopus = arr[0]
const beaver = arr[1]
```

When using new syntax we can achieve the same result as before, but in quicker and more elegant way:

```javascript
const [octopus, beaver] = [🐙, 🦫, 🦭]
// octopus = 🐙
// beaver = 🦫
```

We have to keep in mind that destructuring uses copies of elements - the source array remains unchanged.

### Skipping, ...rest and default values

In the previous example we can see that consecutive elements of the array have been assigned to new variables. Now you can ask - what if we want to skip one or more elements - is it even possible? Yep! Ignoring values while destructuring arrays can be done with the following syntax:

```javascript
const [octopus, , seal] = [🐙, 🦫, 🦭]
// octopus = 🐙
// seal = 🦭
```

More complex case of omitting elements of an array is using `...rest` operation. It allows to assign array's elements which we don't need to store in separate variables as new array.

```javascript
const [octopus, ...rest] = [🐙, 🦫, 🦭]
// octopus = 🐙
// seal = *[🦫,🦭]*
```

Another helpful technique which can be used with destructuring is assigning default values to variables. When one element of the array is `undefined` we can assign it previously defined value:

```javascript
const zoo = [undefined, 🦫, 🦭]
const [octopus = 🐙, 🦫, 🦭] = zoo
// octopus = 🐙
// beaver = 🦫
// seal = 🦭
```

### Destructuring objects

We can use the same techniques while working with objects. Let's take a look at similar example as in the beginning of this article, but in this case for objects. Again, it's easy to spot that thanks to using destructuring we're getting more readable and clearer code

```javascript
// Old syntax
const dinner = {
    soup: 🍜,
    steak: 🥩,
    drink: 🥤,
}

const soup = dinner.soup
const steak = dinner.steak
const drink = dinner.drink

// New syntax
const { soup, steak, drink } = dinner
// soup = 🍜
// steak = 🥩
// drink = 🥤
```

### Default values once again, renaming variables

For objects we can define default value as well:

```javascript
const dinner = {
    soup: undefined,
    steak: 🥩,
    drink: 🥤,
}

const { soup = 🍜, steak, drink } = dinner
```

> IMPORTANT: default value won't be used when the property has a value equal to `null` - `null` will be returned despite defining a default value.

What if key inside the object is the same as the name of previously defined variable inside our code? We can't have two independent variables with the same name inside the same scope. In this case assigning value to a variable of any name is the solution:

```javascript
const dinner = {
    soup: 🍜
    steak: 🥩,
}

const { soup: ramen } = soup
// ramen = 🍜
```

### Nested destructuring

Previous examples were relevant to simple objects. In case of deeply nested objects destructuring is possible as well:

```javascript
const fruit = {
    berries: {
        strawberry: 🍓,
    },
}

const { berries: { strawberry }} = fruit

// strawberry = 🍓
```

In case of objects, similarly as for arrays, we can use `...rest` operator:

```javascript
let plane = {
    model: "A321",
    pilot: 👩🏻‍✈️,
    seat: 💺,
}

let { model, ...rest } = plane

// model = "A321"
// rest.pilot = 👩🏻‍✈️
// rest.seat = 💺
```

One last use of destructuring is inside a function. Thanks to this we can operate on object properties passed to a function as an argument. If we know properties of the object being passed as an argument to a function we can use destructuring as following:

```javascript
const user = { id: 0, username: "Andrew" }

function helloAndrew({ id, username }) {
    console.log(`hi ${username}`)
}

helloAndrew(user)

// 'hi Andrew'
```

The folks who are familiar with React can notice a recurring pattern. According to best practices it is desired to destructure `props` object in React's components. While destructuring React components we do exactly the same as shown in the previous example. Below is the example for React's functional component returning a button with text.

```javascript
const Button = ({ text, type }) => {
    return <button type={type}>{text}</button>
}

// the other way
const Button = props => {
const { text, type } = props

    return <button type={type}>{text}</button>
}
```

### Summary

It's hard to deny that code with destructuring assignments is easier to read and much better structured. Javascript's capabilities on this, prior to ES6, were somewhat limited, and this led to a lot of redundant code.

Knowing all the possibilities described in this article, we can certainly make our code more friendly both for us and for other developers with whom we have the opportunity to work.