Object Destructuring in JavaScript
Object destructuring was introduced in ES6 and has since aided developers in extracting properties from objects and binding them to variables. Even more, with object destructuring developers are able to extract multiple properties in one statement, set default values if a property does not exist, and access properties within nested objects.
In the before times…
In order for developers to extract properties from an object they would need to write the following code —
let cat = {
name: 'Bill',
age: 18
};let name = cat.name;
let age = cat.age;name; // 'Bill'
age; // 18
In this version of property extraction, the name binding is mentioned twice, as is the case for age. This isn’t very DRY (Don’t Repeat Yourself) code.
Now…
This is where object destructing has made significant improvements — you can instead read a property and assign the value to a variable without having to duplicate the property name. Further, developers can read multiple properties from the same object in only one statement.
const cat = {
name: 'Bill',
age: 18
}; const { name, age } = cat;name; // 'Bill'
age; // 18
const { name, age } = cat; is the destructuring assignment, it defines the name and age variables and assigns to them the values of cat.name and cat.age.
Comparing the two approaches, it is clear that destructuring is the better choice as neither the property names nor the object variables are duplicated.
How To: Extract a Property
The syntax for object destructuring is fairly straight forward —
const { identifier } = expression;
identifier is the name of the property you wish to access and expression is the object. After the destructuring has occurred, the variable identifier contains the property value.
The property accessor equivalent to this is —
const identifier = expression.identifier;
Here is the destructuring example from above again —
const cat = {
name: 'Bill',
age: 18
};const { name } = cat; name; // 'Bill'
const { name } = cat defines the variable name and initializes it with the value of the cat.name property.
How To: Extract Multiple Properties
In order to destructure an object into multiple properties, list as many properties as desired adding commas to seperate —
const { identifierOne, identifierTwo, identifierThree, ...etc } = expression;
Once again, identifierOne and so on are the names of the properties wanted to be accessed and expression is the object. These identifiers will contain the corresponding property values from the object.
In our first example, multiple property extraction can be observed —
const cat = {
name: 'Bill',
age: 18
};const { name, age } = cat;name; // 'Bill'
age; // 18
const { name, age } = cat creates two variables (name and age) with the values assigned to cat.name and cat.age respectively.
How To: Utilize Default Values
When a destructured object does not have the property that is written in the destructuring assignment, this variable is assigned a value of undefined.
const cat = {
name: 'Bill',
age: 18
};const { numOfKittens } = cat;numOfKittens; // undefined
This happens because the property of numOfKittens does not exist in the cat object.
To remedy this, you are able to set a default value to the property if it does not exist within the destructured object —
const { identifier = defaultValue } = expression;
Much like assigning a default argument in a function declaration, the above application serves the purpose of assigning a default value to an object property if it does not exist.
Here is the above example with a default value employed —
const cat = {
name: 'Bill',
age: 18
};const { numOfKittens = 25 } = cat;numOfKittens; // 25
So instead of undefined, numOfKittens defaults to 25.
How To: Alias
Another feature of object destructuring is the ability to create variables of different names than the object’s property names — via aliasing.
const { identifier: aliasIdentifier } = expression;
Above, identifier is the name of the property to be accessed, aliasIdentifier is the variable name you have chosen, and expression is the object being destructured. After the destructuring has occurred, aliasIdentifier now contains the object’s property value.
const cat = {
name: 'Bill',
age: 18
}; const { name: firstName } = cat;firstName; // 'Bill'
How To: Extract Properties from Nested Objects
Often objects are nested within other objects, thus some properties can contain objects. You are still able to use object destructuring to access these objects with multiple levels —
const { nestedObjectProperty: { identifier } } = expression;
Above, nestedObjectProperty is the name of the property that contains a nested object, identifier is the property name you wish to access within this nested object, and expression is the outer object.
Once destructured, identifier will contain the property value of the nested object. The extent of nesting able to be extracted from is limitless, in order to extract from further levels of nested depth you add more nested curly brackets —
const { propertyOne: {propertyTwo: { propertyThree: { … } } } } = expression;
For example —
const cat = {
name: 'Bill',
age: 18,
kittens: {
kittenName: 'Phil'
}
};const { kittens: { kittenName } } = cat;kittenName; // 'Phil'
This destructuring allowed us to access the kittenName property from the nested object.
How To: Extract a Dynamic Name Property
Another helpful attribute of object destructuring is the ability to extract variable properties with dynamic names —
const { [propertyName]: identifier } = expression;
propertyName evaluates to the property name, identifier is the variable name created after destructuring, and expression is the object to be destructured.
const cat = {
name: 'Bill',
age: 18
}; const property = 'name';const { [property]:name } = cat;name; // 'Bill'
const { [property]:name } = cat is an object destructuring that assigns to the variable name the value of cat[property], and this property is a variable that holds the property name.
How To: Use Rest in Object Destructuring
Rest is helpful in collecting the remaining properties of an object after destructuring.
const { identifier, ...rest } = expression;
After destructuring, the variable identifier will contain the property value, and rest variable is a plain object that contains the remaining properties of the object.
In this example we will extract the name variable and keep the rest of the properties —
const cat = {
name: 'Bill',
age: 18
};const { name, ...remainingProperties } = cat; remainingProperties; // { age: 18 }
const { name, …remainingProperties } = cat extracts the name property, while the remaining properties (age) are collected into the the variable remainingProperties.