JavaScript object destructuring - Understand it the easiest way...
Perhaps you haven't heard about the ES6 feature or you just don't get it. This guide explains everything you need to know about object destructuring.
If you find this post useful, you should probably find my other contents useful too, consider following me on Twitter to read more of my content.
In a previous post , I discussed about array destructuring in JavaScript which is a feature that was introduced in ES6. It allows us to unpack / copy values from a JavaScript array into individual variables using a clearer and shorter syntax. In this post, I'll be discussing about Object destructuring which is almost the same thing as array destructuring. The only difference is that in Array Destructuring, values are unpacked from an array while in Object Destructuring, values are unpacked from an object.
Before ES6 was introduced, the major approach to unpacking values from an object is by accessing each value through its key in the object containing it, then store the value in any individual variable which can have any name.
// Before ES6
var obj = { width: 40, height: 34 };
var width = obj.width, height = obj.height;
console.log("width::> " + width); // 40
console.log("height::> " + height); // 34
In the example above, the object obj
contains 2 key/value pairs. The first key is width
and the second key is the height
. The values of these 2 keys are then copied into individual variables named width
and height
respectively. The name of these variables can be anything used to name variables in JavaScript when you're using the syntax above. I named the variables with the keys in the object for clarity.
Destructuring an object in ES6
With the introduction of ES6, it became relatively easier to copy values stored in a JavaScript object. The only limitation is that the names of the variables to store the values copied from an object must be the same with the key storing that value inside that object. But it actually isn't a limitation because the syntax also supports new variable names but with some additional syntax requirements. We'll discuss about this later in this article. Let's take a simple example of object destructuring in JavaScript using the ES6 syntax
// Using object destructuring in ES6 ( Key must be the same with variable_name )
let obj_1 = { width_1: 100, height_1: 54 }
let { width_1, height_1 } = obj_1;
console.log("width_1::> " + width_1); // 100
console.log("height_1::> " + height_1); // 54
In the above example, the object obj_1
was declared on line 2. It contains 2 key/value pairs which are width_1
and height_1
. The object after the let keyword contains the variables that will store the values unpacked from the obj_1
object. The variables look into the object on the other side to find keys that have the same name as them. When there's a key with the same name as the variable, the variable is assigned the value of the key. If not, the variable becomes undefined. Therefore, the width_1
variable stores the value of the width_1
key in the obj_1
object and the same goes for the height_1
variable. The image below illustrates how object destructuring works.
Declaring the variable before assigning values
You can first declare the variables that will store the values unpacked from an object then assign values to them when the object is destructured. That is, declaration and assignment in 2 different statements. To do that, the second statement (where object is destructured) has to be wrapped in a pair of parentheses '()' and should end with a semicolon ';'. See the example below,
// Declaring variables before assigning values
let width_2, height_2;
({ width_2, height_2 } = { width_2: 70, height_2: 80 });
console.log("width_2::> " + width_2); // 70
console.log("height_2::> " + height_2); // 80
In the above example, the variable width_2
takes the value of the key width_2
in the containing object (on the right side). Same goes for height_2
.
Disarranging the variables doesn't affect anything
In the previous examples, the order of the variable names has been the same for the keys in the object containing values to be unpacked. This is not important because the variables match their values by names of keys not by their positions. See example below
// Order is not important
let my_obj = { my_width: 65, my_height: 98 }
let { my_height, my_width } = my_obj;
console.log("my_width::> " + my_width); // 65
console.log("my_height::> " + my_height); // 98
In this example, the object my_obj
has 2 keys. The first key is my_width
and the second is my_height
. The object is destructured in the second line. Note that the order in which the variable names are arranged in the object on the left differs from the order in which the keys are arranged in the object my_obj
. This doesn't change anything, the my_height
variable still takes the value of the my_height
key in the my_obj
object and the my_width
variable takes the value of the my_width
key in the my_obj
object. Therefore, my_height
is equal to 98
and my_width
is equal to 65
.
Using new variable names
In all previous examples, we've been naming the variables (variables that stored values unpacked from object) based on the keys that contain their values. This is a syntax requirement. But it's also possible to specify another variable name instead of naming the variable based on the key. To do that, the new variable name should be assigned as a value to the name that normally would have stored the value gotten from the object. Consider the example below,
// Using new names for the object keys
let { x: width_3, y: height_3 } = { x: 11, y: 17 }
console.log("width_3::> " + width_3); // 11
console.log("height_3::> " + height_3); // 17
Here, the let keyword declares the variables. The first object-like part of the statement { x: width_3, y: height_3 }
defines the variables that will store values unpacked / copied from the object on the right side. The object has 2 keys x
and y
. When the object is destructured, the value is not stored in the keys but in the variables assigned to them. Therefore, the value of x
goes into width_3
and the value of y
goes into height_3
. The image below illustrates the process.
Therefore, width_3
is equal to 11
and height_3
is equal to 17
.
Using default values
Just like in array destructuring , a default / fallback value for a variable can be specified when destructuring objects. In case there is no corresponding key in the object where values are copied from, the default value is used. Consider the following example
// Using default values
let myObj = { myWidth: 345, myHeight: 214 }
let { myWidth, myBreadth = 548, myHeight } = myObj;
console.log("myWidth::> " + myWidth); // 345
console.log("myBreadth::> " + myBreadth); // 548
console.log("myHeight::> " + myHeight); // 214
Notice in the example above that the myBreadth
variable has been assigned a value of 548 in the destructuring syntax which is the default / fallback value for it.
After destructuring, the myWidth
variable takes the value of myObj.myWidth
and the myHeight
variable takes the value of myObj.myHeight
. Since there is no myBreadth
key in the myObj
object (myObj.myBreadth
), the myBreadth
variable takes the default value that was assigned to it which is 548
.
Note::- The default value must be assigned to the variable in the statement where the destructuring takes place not before it. If you are declared the variable in another statement, don't assign the default value to it there. Assign it when you are including it in the destructuring syntax not when you declared it.
Using default values with new variable names
In the previous example, we assigned a default value to the myBreadth
variable which served as the variable name. Suppose we want to use another variable name and still assign a default value, we just have to specify the new variable name as a value to myBreadth
and equate the new variable name to whatever we want the default value to be. Consider the following example
// Using default values with new variable names
let object1 = { a: 18, b: 98 }
let { a, d: x, c: y = 54, } = object1;
console.log("a::> " + a); // 18
console.log("x::> " + x); // 98
console.log("y::> " + y); // 54
In this example, the variable a
stores the value of object1.a
. Key b
takes the value of object1.b
and stores it in variable x
. Key c
in the container object (object after the let keyword) doesn't have a corresponding object1.c
and it's supposed to store its value in variable y
. Therefore, the default value assigned to y
is stored in it which is 54
.
Accessing keys that do not exist
// Attempting to access a key that does not exist
let newObj = { nWidth: 217, nHeight: 980 }
let { nWidth, nHeight2 } = newObj;
console.log("nWidth::> " + nWidth); // 217
console.log("nHeight2::> " + nHeight2); // Undefined
Any variable that tries to access keys that do not exist in the destructured object remain undefined. In the above example, nHeight2
variable is undefined because there's no nHeight2
key in the newObj
object and there's also no default value specified.
I hope everything discussed here is understood. You can read a shorter version of this article on twitter...
If you'll like to read about array destructuring, read this article.
If you like this article, you'll probably like to read my content on Twitter. Kindly follow me on Twitter. You can also follow me if you are a member of hashnode @abdulramonjemil.
Also, consider subscribing to my newsletter to get a message whenever I post another content here on my blog. Thanks a lot in advance.