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.
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:
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, 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
let numObj = {1: 'a', 2: 'b'}
I can access values with bracket notation
numObj[1]
//"a"
numObj['1']
//"a"
but dot notation results in an error:
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:
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:
let { a, b } = myObj
a
//1
b
//2
During destructuring, I can also assign new variable names:
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
:
let myNestedObj = {a: 1, b: {c: 3, d: {e: 4}}}
To assign the values of a
and d
I can destructure like so:
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:
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:
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!