JavaScript object destructuring - Understand it the easiest way...

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.

Play this article

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.

Image illustrating the process of Object destructuring

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.

Image illustrating the process of using new variable names when destructuring objects

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.