Object Destructuring in JavaScript
Tags: javascript
Published: 2020-08-14 18:06:50

I recently found myself struggling with adding CSS classes to a React component. Once I understood the `classes` object and how it was created, most of my confusion stemmed from basic object destructuring. So I decided to write this post to solidify my understanding of destructuring assignments in JavaScript! Hopefully it will provide some clarity for others working through this concept as well.

### A Quick Review of Objects

An object literal in JavaScript is constructed with key, value pairs separated by a colon. Each key, value pair is separated from the next pair by a comma. Values can be any datatype - arrays, objects, strings, functions, etc - while keys must always be strings, or something that JS can convert to a string, like a number. 
```js
let myObj = {a: 1, b: 2}
```
In `myObj`, `a` and `b` are both strings and JS gives me the shortcut of skipping writing the quotes around those. 

To access values of `myObj`, I can use either dot notation or bracket notation:
```js
myObj.a
//1
myObj["a"]
//1
```
In order to use dot notation to access an object property, the key must be a valid JavaScript identifier. From the [MDN web docs](https://developer.mozilla.org/en-US/docs/Glossary/identifier), an identifier is a "sequence of characters in the code that identifies a variable, function, or property". Importantly, an identifier cannot begin with a digit. So, if I created an object like so
```js
let numObj = {1: 'a', 2: 'b'}
```
I can access values with bracket notation
```js
numObj[1]
//"a"

numObj['1']
//"a"
```
but dot notation results in an error:
```js
numObj.1
// Uncaught SyntaxError: Unexpected number
```

Note that with bracket notation, JavaScript coerces `1` to the string `"1"`. However, `myObj[a]` would result in an error - `a` is expected to be a variable in that case.

### Basic Destructuring

A destructuring assignment allows the mass assignment of variables to object (or array) values. Using the previous `myObj` for example, I could assign variables to access values like so:
```js
let a = myObj.a
let b = myObj.b
a
//1
b
//2
```
Or with a destructuring assignment, I can assign both those variables in one line:
```js
let { a, b } = myObj
a
//1
b
//2
```

During destructuring, I can also assign new variable names:
```js
let {a: first, b: second} = myObj
first
//1
second
//2
```
In this case, `a` and `b` are not simultaneously assigned as variables.

### Nested Destructuring

Destructuring assignments can also handle nested objects. Let's start with `myNestedObj`:
```js
let myNestedObj = {a: 1, b: {c: 3, d: {e: 4}}}
```
To assign the values of `a` and `d` I can destructure like so:
```js
let {a, b: { d }} = myNestedObj
a
//1
d
//{e: 4}
b
//undefined
```
In this case, `b` is a 'step' to access `d`, and is not assigned in the destructuring. I can add the assignment of `b` like this:
```js
let {a, b, b: { d }} = myNestedObj
b
//{c: 3, d: {…}}
```
Of course, I could destructure further to access `e` and assign new variable names if I felt like it too:
```js
let {a: outer, b: { c, d: { e: inner }}} = myNestedObj
outer
//1
a
//undefined
b
//undefined
c
//3
d
//undefined
inner
//4
e
//undefined
```

### The Power of Destructuring

Destructuring is an excellent way to access the properties of an object that might be passed into a function or as the `props` of a React component. Rather than write a line of code to assign a variable to each property, or use dot or bracket notation every time for access, objects can be destructured for code clarity and ease of writing. Destructuring can even happen in a function definition by destructuring the arguments! Overall, it's an incredibly useful concept and important to become comfortable with if you are developing in JavaScript. 

Thanks for reading!