How Destructuring Works in Javascript


What is Destructuring?
Destructuring is an expression in Javascript that dissects data structures, mainly unpacking values from arrays and properties from objects, and directly turning them into readymade variables. Here is an example of destructuring.
const foodItems = ["rice", "beans", "flour"]
const[firstFoodItem, secondFoodItem, thirdFoodItem] = foodItems
console.log(firstFoodItem) // outputs rice
console.log(secondFoodItem) // outputs beans
console.log(thirdFoodItem) // outputs flour
On a regular day, you would have defined the variables as shown below. But as you can see, destructuring lets you rewrite the code in fewer lines. This is especially important in large data structures where short, readable, and concise code is important.
const foodItems = ["rice", "beans", "flour"]
const firstFoodItem = foodItems[0]
const secondFoodItem = foodItems[1]
const thirdFoodItem = foodItems[2]
console.log(firstFoodItem) // outputs rice
console.log(secondFoodItem) // outputs beans
console.log(thirdFoodItem) // outputs flour
Meanwhile, making distinctions between destructured and normal objects or arrays can be confusing. But you must note that an array or object value is on the right side of the assignment, just like in this example
const array = [2, 4. 6. 8. 10]
But in destructuring, the arrangement is the other way around. The destructuring expression stay on the left-hand side while the array or object maintains its right-side position as shown in the example below
const array = [2, 4, 6, 8, 10]
const[a, b, c, d] = array
console.log(a) //returns 2.
It is worth knowing though, that object and array destructuring — including their syntaxes — are different. More of these differences will be explained later in the article.
Beyond arrays and objects, destructuring syntaxes and patterns can also differ based on their functionality. There are two main categories of destructuring patterns, bindings and assignments.
While both binding and assignment patterns can help you unpack object and array values, both perform markedly different functionalities. Binding declares variables and renames properties while assignments assign values without declaring.
The Binding Pattern
Binding attaches each value or property to a variable. It usually starts with a variable declaration using const
, var
or let
. Binding is a good way to rename and declare an object property or array value as a variable for later usage. Instead of writing const number = obj.a
, binding provides a more concise way of attaching obj.a
to number
In the const scores
declaration below, binding helps bounds values within the scores
object. Here, three newly declared variables, a
, e
and f
are bound to existing scores properties. While a
is bound to scores.a
, e
is attached to scores.b.c
returning a value of 10 and f
to scores.b.d
, which is 12
.
const scores = { a: 9, b: { c: 10, d: 12 } };
const {
a,
b: { c: e, d: f },
} = scores;
console.log(e) // returns a value of 10
console.log(f) //returns a value of 12
//Here, three variables are bound "a", "e" and "f". a is bound to a, e to 10 and d to 12
The regular well-known alternative is just declaring it with a const
or let
. Take for example
const a = scores.a,
const e = scores.b.c
const f = scores.b.d
But you must keep in mind that variables declared with const
cannot be reassigned, even in destructuring. Hence, in the cases above, the values of e
and f
will always be 10
and 12
, respectively. You can’t reassign them.
To enable reassigning, you must declare the appropriate values you want with the let
declaration, as demonstrated in the code below.
const scores = { a: 9, b: { c: 10, d: 12 } };
const {a} = scores // the value of a is constant. It can never change
let { b:{ c: e, d: f }} = scores // while e = 10 and f = 12, their values can be reassigned
Here, a
is a constant while e
and f
are not. Hence, e
and f
can be reassigned, even after being bound.
The Assignment Pattern
Unlike binding, it neither starts with a variable declaration like let
or const
nor renames variables. Rather, it assigns values to Javascript expressions. Take, for example.
const myScores = []
const scores = { a: 9, b: 10, c: 15, d: 20 };
({a:myScores[0], b:myScores[1], c:myScores[2], d:myScores[3]} = scores)
console.log(myScores) // Outputs [9, 10, 15, 20]
In the example above, the myScore
declaration is an empty array. The assignment pattern helps input values to myScores
from the const scores
object, by destructuring scores and calling myScores
index expressions within it. Therefore, each index expressed takes the corresponding values in scores constant.
While the binding pattern seeks to replace the variable declaration, assignment patterns directly target values.
What to Keep In Mind While Writing an Assignment Pattern
Assignment patterns must be nested in a parenthesis
(...)
. Otherwise, Javascript will treat the code as a block instead of an object being destructured. For example({a:myScores[0], b:myScores[1], c:myScores[2], d:myScores[3]} = scores) //correct syntax {a:myScores[0], b:myScores[1], c:myScores[2], d:myScores[3]} = scores // syntax error
You can’t use assignment pattern with compound assignments like +=, -=, *= or /=
This will return as an error
({a:myScores[0], b:myScores[1], c:myScores[2], d:myScores[3]} += scores) //syntax error
How to Omit Values Via Destructuring
When faced with large datasets and a lot of unused values, you might need just a few values don't have to define the others. Besides, most code linters complain about unused variables.
How do you omit values and communicate to Javascript and your team that you intentionally left them out? Javascript destructuring offers some solutions.
Using the Rest Parameter
Leaving Blank spaces
Using the underscore to communicate a useless variable
Using the Rest Parameter
After binding the values you need, a rest parameter can help categorize the remaining values under a defined constant. As shown below, after declaring one
and two
, I categorized the remaining under the rest constant
const numbers = [1, 2, 3, 4, 5]
const[one, two, ...rest] = numbers
console.log(one) //outputs 1
console.log(two) //outputs 2
console.log(rest) // outputs [3, 4, 5]
Alternatively, here is an object destructured with the rest parameter. Here, the remaininingNumbers
returned an object containing the remaining values.
const myNumbers = {
a:1,
b:2,
c:3,
d:4,
e:5
}
const { a:one, b:two, c:three, ...remainingNumbers} = myNumbers
console.log(one) //outputs 1
console.log(two) //outputs 1
console.log(three) //outputs 3
console.log(remainingNumbers) //outputs {d:4, e:5}
However, when using the rest property never add a trailing comma after the rest parameter or declare another variable after the last property for example
const numbers = [1, 2, 3, 4, 5]
const[one, two, ...rest, ] = numbers //SyntaxError: Rest element must not have a trailing comma
const numbers = [1, 2, 3, 4, 5]
const[one, two, ...rest, four] = numbers //SyntaxError: Rest element must be the last element
Combining Rest with the Length Propety
Another way you can use the rest parameter in destructuring is by combining it with the length property. Let’s say for instance.
A regular length property can be used this way.
const numbers = [1, 2, 3, 4, 5]
const{length} = numbers
console.log(length) //This outputs 5 which is the array length
With the rest parameter, it can be used this way.
const numbers = [1, 2, 3, 4, 5]
const[one, two, three, ...{length}] = numbers
console.log(one) //outputs 1
console.log(two) //outputs 2
console.log(three) //outputs 3
console.log(length) //This outputs 2, which is the length of the remaining values after destructuring the first three values
But not this way. Length property used with rest does not work on objects.
const {a:one, b:two, ...{ length }} = {a:1, b:2, c:3, d:4, e:5, f:6};
console.log(length); // incorrect syntax because in this case, length can’t be used with object properties.
Using a Rest parameter in a Rest parameter in yet another Rest parameter 🥱
Yes, that is possible too. You can define a rest property in another rest property as far as each rest property ends its scope and does not have a trailing comma. Here is a proper explanation.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,]
const[one, two, three, ...[four, five, ...[six, seven, ...remainingNumbers]]] = numbers
console.log(remainingNumbers) //outputs [8, 9, 10]
As you can see above, three rest parameters were declared with each housing variables, while the item being a rest arrray. Then in that rest array, new variables are defined and anotehr rest property nested, until the remaining values is categorized with ...remainingNumbers
, which is also a rest property. Below is a list of each rest parameter defined.
...[four, five, ...[six, seven, ...remainingNumbers]]
...[six, seven, ...remainingNumbers]
...remainingNumbers
Leaving Blank Spaces
Unlike the rest parameter that target the last properties after all else has been defined, leaving a blank space can help you omit values in the middle. Just leave the declaration blank and add a comma after.
In the case below,, the second value gets omitted by adding an extra comma without a variable declaration before it.
const [one, , three] = [1, 2, 3]; // here, the second value is omitted by adding an extra comma without a declaration before it
console.log(one, three); // outputs 1, 3
But you might want to be pragmatic about it, especially if you are working with larger datasets because you don’t want your colleagues or even you to start counting commas when reviewing your code later 😀.
Check the example below. How many commas are you willing to count?
const [one, two, , four, , six, seven, eight, , ten ] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // here 3, 5 and 9 were ommited in the declaration
console.log(one, two, four, six, seven, eight, ten ) //outputs 1 2 4 6 7 8 10
To make your code more readable, you can add the values of the omitted parts and just comment them out as shown in this example. That way, future references won’t be too difficult,
const [one, two, /*three*/, four, /*five*/, six, seven, eight, /*nine*/, ten ] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // here 3, 5 and 9 were ommited in the declaration
console.log(one, two, four, six, seven, eight, ten ) //outputs 1 2 4 6 7 8 10
Here, the omitted parts were added but commented out. This makes the code more understandable and readable for future reference.
Using an Underscore
As a general rule in Javascript, you can use an underscore to tell the computer and fellow developers that you had to define a variable but you don’t intend to use it. Here is an example of how it is used in destructuring.
const [_one, _two, three, four] = [1, 2, 3, 4,];
console.log(one) //outputs undefined
console.log(two) // outputs undefined
console.log(three) // outputs 3
console.log(four) // output 4
Even though it is defined, your computer will run one and two as undefined because you added an underscore to signify that you are not using them. This approach makes code more readable than just adding extra commas.
Object and Array Destructuring
As can be easily deduced, object destructuring is used for defining variables in an object while array destructuring helps decouple values within an array or other iterables. Due to the different inherent behaviours of objects and arrays, each has its distinct destructuring syntaxes and behaviours. As a general rule, keep the following in mind.
Object destructuring syntax is primarily used for object properties
Object destructuring can also be used for arrays when we treat array indexes as property names and array values as property values.
Array destructuring is used to decouple arrays
Array destructuring can also be used for other iterables like map, forEach, and for loop methods.
Array destructuring can't work on non-iterables like objects. But they might work when objects are converted to custom iterables with
*[Symbol.iterator]
and looped throughPrimitive values like numbers and null cannot be destructured.
Array Destructuring
Basically, array destructuring is used to unpack any iterable. Hence, beyond simple arrays, it can destructure values in for loops, and map methods, amongst others.
Here is an example of a simple array destructuring. Where we decoupled const myHobbies
constant
const myHobbies = ["reading", "traveling", "hiking"]
const[hobbyOne, hobbyTwo, hobbyThree] = myHobbies
console.log(hobbyOne) //outputs reading
Alternatively, the destructuring can be written this way, where the array values sit directly at the right-hand side of the assignment.
const[hobbyOne, hobbyTwo, hobbyThree] = ["reading", "traveling", "hiking"]
console.log(hobbyOne) //outputs reading
console.log(hobbyTwo) //outputs traveling
console.log(hobbyThree) //outputs hiking
But, what happens if the variables declared in destructuring are more than the array? The extra remaining variables remain undefined. Here is a perfect showcase.
In the case below, hobbyThree
and hobbyFour
returned undefined
because there is no corresponding value within the source array.
const[hobbyOne, hobbyTwo, hobbyThree, hobbyFour] = ["reading", "traveling"]
console.log(hobbyOne) //outputs reading
console.log(hobbyTwo) // outputs traveling
console.log(hobbyThree) // outputs undefined
console.log(hobbyFour) // outputs undefined
What also happens when we don’t want to use all the values within an array? As you can see in the example below, you can decide to skip the third item in the array — in this case ants
— by adding an extra comma after the second declaration. Read more about skipping unused values in destructuring here
const animals = ["cow", "goat", "ants", "fox"]
const[firstAnimal, secondAnimal, , thirdAnimal] = animals
console.log(firstAnimal) //outputs cow
console.log(secondAnimal) // outputs goat
console.log(thirdAnimal) // output fox
Destructuring Arrays within Arrays
For arrays nested in arrays, you can dissect them as shown below.
As shown below, the destructuring maintains the same pattern as the original array
const nestedArray = [1, [2, 3], 4];
const [one, [two, three], four] = nestedArray;
console.log(one); // outputs 1
console.log(two); // outputs 2
console.log(three); // outputs 3
console.log(four); // outputs 4
Destructuring Arrays Returned By Functions
A function returning an array can be destructured by calling the function on the right side of the assignment.
Examine the code below, where the evenNumber
returned an array, which is then decoupled and attached to variables a
, b
and c
function evenNumber() {
return [2, 4, 6]
}
const[a, b, c] = evenNumber()
console.log(a) // outputs 2
console.log(b) // outputs 4
console.log(c) // outputs 6
You can also omit values from the array returned by a function. In the example below, 4 gets omitted after adding a comma without a variable after the first value. This jumps the second value and moves to the third.
const evenNumber = () => {
return [2, 4, 6,]
}
const[a, , b] = evenNumber()
console.log(a) //outputs 2
console.log(b) // outputs 6
// 4 gets omitted by adding an extra comma after the first value.
Below is a more advanced destructuring of a function. Unpacking works with function parameters where the function returns parameters as array values that can be used as arguments when destructuring the function.
In the example below, we passed a, b
as parameters to the calculate function and asked the same function to return an array of 3 values: a+b
, a-b
and a*b
When destructuring we bound each of these values to the sum
, difference
and product
variables respectively. By replacing a
and b
parameters with 5
and 3
, a equals 5 while b equals 3.
function calculate(a, b) {
return [a + b, a - b, a * b];
}
const [sum, difference, product] = calculate(5, 3);
console.log(sum); // outputs 8.
console.log(difference); // outputs 2
console.log(product); // outputs 15
Hence, the values gets destructure this way
const sum = a + b = 5 + 3
which is 8
const difference = a - b = 5 - 3
which is 2
const product = a b = 5 * 3
which is 15
Dissecting Iterabes with Array Destructuring
Even though all arrays are iterables not all iterables are arrays. But what is an iterable?
An iterable is an object that can be looped through by allowing access to its elements one by one. Typically they can allow access to their elements via methods like Array.from()
or for
loops. Examples of iterables include
Arrays
Strings
Maps. (different from .map() method wich is an argument)
Sets
Methods added to non-iterables.
Destructuring a String
Being iterable, a string can be decoupled by using the array destructuring method as shown below.
As you can see, individual characters within the string gets destructured.
const str = "Hello";
// Extract individual characters
const [firstChar, secondChar, thirdChar] = str;
console.log(firstChar); // H
console.log(secondChar); // e
console.log(thirdChar); // l
Destructuring new Map()
.
Keep in mind that new Map()
object is different from .map()
method. While new Map()
are used to store key value pairs, map method is an array method used to iterate over arrays.
Here is an example of its new Map()
object destructuring.
const myMap = new Map([
["name", "Alice"],
["age", 25],
]);
const[a, b] = myMap
console.log(a) // outputs name: Alice
console.log(b) // outputs age: 25
Destructuring a new Set()
Sets
objects in JavaScript are collections of unique values, They make it simple to eliminate duplicates from an array. Here is how to destructure a Set
.
const mySet = new Set([1, 2, 3, 1]);
const [a, b, c, d] = mySet;
console.log(a); // outputs 1
console.log(b); // outputs 2
console.log(c); // outputs 3
console.log(d); // outputs undefined
As you can see above, the last value d
, returned undefined because a normal set method eliminates duplicate values. Since 1 had been defined with a prior, with a, defining its duplicate with d
outputs undefined.
Destructuring with Array Iteration Methods
When working with array methods like .map()
or .forEach()
, destructuring can simplify the syntax. Here instead of redefining values within the nested object after iterating, destructuring provides an better way.
const points = [[10, 20], [30, 40], [50, 60]];
points.forEach(([x, y]) => {
console.log(`x: ${x}, y: ${y}`);
});
// Output:
// x: 10, y: 20
// x: 30, y: 40
// x: 50, y: 60
The alternative could have been
const x = points.[arrayIndex].[0]
const y = points.[arrayIndex].[1]
// where arrayIndex is the index of the points main array
Using the Symbol Iterator with Array Destructuring on Objects
Array destructuring can’t work on a regular object since it is non-iterable. But you can flip the script by converting an object to an iterable using the *[Symbol.iterator]
method and looping over its values. Here is an example
const myObj= {
*[Symbol.iterator]() {
for (const v of [5, 6, 7, 8]) {
console.log(v);
yield v;
}
},
};
const [a, b, ...rest] = myObj; // Logs 5, 6, 7, 8
console.log(a) // outputs 0
console.log(b) // outputs 1
console.log(rest); // [2, 3] (an array)
In the example above, the loop returns the first value before moving to the next. Thereby, creating an array of the looped values. However, it is important knowing that until the variable bindings are called, the values iterated over cannot be destructured or assigned to the constants.
Default Values in Array Destructuring
No one likes an undefined variable, including the system. And defining a default variable might be the perfect way out of the unease.
A default variable serves as a nice placeholder value for your arrays in case the array does not contain any value. It is assigned with the =
assignment. While a destructured empty array returns undefined, when default values are added in the destructuring, the empty array returns the preset values.
In the same stretch, an array with missing values will fill its gaps with default values. Here is an example below where myNames
is an empty array but gets filled up with default values named in the destructuring.
const myNames = []
const[firstName = "Jack", lastName = "Doe", nickName = "Jackie"] = myNames
console.log(firstName) // outputs Jack
console.log(lastName) // outputs Doe
console.log(nickName) // outputs Jackie
Also, in the example below, the myNames
values are not complete, hence it fills the missing gaps with the default values, while maintaining its available values. Default values are only useful when your array data is incomplete or empty.
const myNames = ["Jane", "Walker"]
const[firstName = "Jack", lastName = "Doe", nickName = "Jackie"] = myNames
console.log(firstName) // outputs Jane
console.log(lastName) // outputs Walker
console.log(nickName) // outputs Jackie
Object Destructuring
An object is anything that returns a key, value pair, and wrapped within a curly bracket in this fashion const myObject = {a: 1, b:2, c:3}
When destructuring an object, the unpacking takes the same syntax as the object. Here is a good example of a basic object destructuring.
const myNames = {
a: "John",
b: "Doe",
c: "Jonny"
}
const {a:firstName, b:lastName, c:nickName} = myNames
console.log(firstName) // outputs John
console.log(lastName) // outputs Doe
console.log(nickName) // outputs Jonny
Here, as you can see above, the a
, b
and c
property keys is declared with variables like firstName, lastName and nickName respectively. An alternative – more cumbersome – approach would have been
const firstName = myNames.a
const lastName = myNames.b
const nickName = myNames.c
Setting Default Values in Object Destructuring
Just like you add default values in arrays, object destructuring also takes defaults by adding the values with the assignment operator =
.
In the example below, myNames
provided the firstName
and lastName
values, hence there is no need to assign their default values. But in the case of nickName
, which is not provided by the object, it returned “Jamie” which is the default.
const myNames = {
a: "John",
b: "Doe",
}
const {a:firstName = "James", b:lastName = "Walker", c:nickName = "Jamie"} = myNames
console.log(firstName) // outputs John
console.log(lastName) // outputs Doe
console.log(nickName) // outputs Jamie
In the same way, default values can be declared on empty objects where the object takes all the values within the default, as shown below.
const myNames = {}
const {a:firstName = "James", b:lastName = "Walker", c:nickName = "Jamie"} = myNames
console.log(firstName) // outputs James
console.log(lastName) // outputs Walker
console.log(nickName) // outputs Jamie
Dissecting Objects Passed as Function Parameters
Objects can also be destructured within functions by passing object properties as parameters and decoupling them within the function. Infact, you can also rename and assign default values to objects within the parameter.
In this case, detstructuring works by unpacking object properties in the functions parameters and calling the object name when relaying the values
Let’s say we want to decouple the data below and use it in a function
const userDetails = {
name: "Jane",
age: "25",
location: "sydney",
family: {
father: "John",
mother: "Moe",
brother: "Jack"
}
}
In its solution below, we passed the userDetails
properties and destructured them within the function parameter. We asked the function to return age
. By calling the function findAge(userDetails)
, it automatically returns the corresponding values
function findAge({ age }) {
return age
}
findAge(userDetails)
console.log(findAge(userDetails)) // outputs 25
In the same way, you can redefine the object properties in the function parameters and even assign it default values. Check out the example below, where redefined the object properties
const userDetails = {
name: "Jane",
age: "25",
location: "sydney",
family: {
father: "John",
mother: "Moe",
brother: "Jack"
}
}
function myDetails({
name:myName,
age:myAge,
location:myLocation,
family: {
father: myFather,
mother:myMother,
brother: myBrother
}}) {
return console.log(myName, myAge, myLocation, myFather, myMother, myBrother)
}
myDetails(userDetails) // outputs Jane, 25, sydney, John, Moe, Jack
In the example above, we decoupled all the values within the myDetails
function and renamed them within the function parameter. userDetails.name
is renamed with myName
, userDetails.age
with myAge
, userDetails.location
with myLocation, and so on.
Then we asked the function to log all these values. By calling the myDetails
function with the userDetails
object as an argument, it relayed all the values within.
Setting Default Values for Object Functions
While unpacking values into variables within a function, you can also set default values using the assignment operator =. Hence, when the object does not provide certain values, the function promptly fills it in with the default value.
Below is a case where default values are defined in the function parameter and attached to an empty object.
function myMeasurement({
length = 15,
width = 10,
height = 20,
mass = 35
} = {}) {
return console.log(length, width, height, mass)
}
const numbers = {
length: 9,
width: 12,
height: 6
}
myMeasurement() // outputs 15, 10, 20, 35
myMeasurement(numbers) //outputs 9, 12, 6, 35
Then, when the function myMeasurements()
is called later on without any passed object parameter, it returns all the defaults. But when the function passed in number object as a parameter, it returned values within the number object while replacing the remaining with default.
Ofcourse, you can write the function without the default value, but then it would require at least one argument when invoked. In its current form, you can call myMeasurements()
without any parameters.
Destructuring Arrays with Object Destructuring
Object destructuring can also be used for arrays when we treat array indexes as property names and array values as property values. In the example below, we define the myNames
indexes as property names and attach new variables to them
const myNames = ["John", "Doe", "Jonny"]
const {0:firstName, 1:lastName, 2:nickName} = myNames
console.log(firstName) //outputs John
console.log(lastName) //outputs Doe
console.log(nickName) //outputs Jonny
Unpacking Nested Objects and Arrays in Javascript
A peculiar situation when unpacking values is when objects and arrays are nested together in a data structure. Sometimes, you find objects within an array which has its own objects like the example below.
There are different approaches to this
Combining Array and Object Destructuring.
Yes, you can combine array and object destructuring to unpack values within a declaration. When doing this, you have to follow the same syntactic sequence used by the object or array.
In the example below where objects are nested in an array, the outer destructuring starts with an array, then skip the first object using a comma, picked the second object and accessed its name property, hence, why the log returned “Fast n Furious”
const movies = [
{ release: 2012, name: "Players" },
{ release: 2015, name: "Fast n Furious" },
{ release: 2018, name: "Mary Kom" },
];
const[, {name}, ,] = movies
console.log(name) // outputs Fast n Furious
Use
for
loops to destructureFor more complex and deeply nested objects and arrays, using a for loop to decouple might be a viable option. Let’s say we want to unpack values in student data shown below. Here, an array of students, nests two objects in which the object’s third property parents is also another object.
const students = [
{
name: "John Michael",
grade: 75,
parents: {
dad: "Jack Michael",
father: "Jill Michael",
},
age: 10,
},
{
name: "Sam Stuart",
grade: 90,
parents: {
dad: "Allen Stuart",
father: "Vicky Stuart",
},
age: 9,
},
];
Here is the solution using the for
loop
const students = [
{
name: "John Michael",
grade: 75,
parents: {
dad: "Jack Michael",
father: "Jill Michael",
},
age: 10,
},
{
name: "Sam Stuart",
grade: 90,
parents: {
dad: "Allen Stuart",
father: "Vicky Stuart",
},
age: 9,
},
];
for (const {
name: n,
grade: g,
parents: { father: f },
} of people) {
console.log(`Name: ${n}, Grade: ${g}, Father: ${f}`);
}
// student[0] outputs "Name: John Michael, Grade: 75, Father: Jack Michael"
// student[1] outputs "Name: Sam Stuart, Grade: 90, Father: Allen Stuart"
As you can see above, we iterated the values with for loop, renamed the name
property with n
, grade
property with g
and father
property with f
. By looping through them, the loop returns the logged values.
Popular Use Cases of Destructuring
Extracting Data from APIs
When working with APIs, the response is often an object or array or even a nesting of both. Destructuring makes it easy to access specific data.
const apiResponse = {
user: {
id: 1,
name: "John Doe",
email: "john@example.com"
},
token: "abc123",
};
const { user: { name, email }, token } = apiResponse;
console.log(name); // John Doe
console.log(email); // john@example.com
console.log(token); // abc123
Nested Data Parsing
When dealing with nested objects or JSON, destructuring simplifies the process. It provides a simpler alternative to declaring variables nested within JSON data one by one
const userProfile = {
id: 101,
personalInfo: {
name: "Sam",
address: {
city: "New York",
zip: "10001"
}
}
};
const { personalInfo: { address: { city, zip } } } = userProfile;
console.log(city); // New York
console.log(zip); // 10001
Parsing URL Parameters
When handling query strings or URLs, destructuring simplifies extracting specific parameters or values.
const myUrl = 'www.abdullahsalaudeen.com/headshot.svg';
const myArr = url.split('.'); // [ 'www', 'abdullahsalaudeen', 'com/headshot', 'svg' ]
const [ , domainName, ,type] = array;
console.log(domainName, type) // outputs abdullahsalaudeen, svg
Working with CSV Data
When processing CSV rows, destructuring makes assigning column values easy.
const row = ["John Doe", "john@example.com", "Software Engineer"];
const [name, email, job] = row;
console.log(name); // John Doe
console.log(email); // john@example.com
console.log(job); // Software Engineer
Error Handling
Destructuring simplifies extracting information from error objects.
try {
throw new Error("Something went wrong!");
} catch ({ message, stack }) {
console.log("Error Message:", message);
console.log("Stack Trace:", stack);
}
Date Manipulation
Destructuring also works well when dealing with dates, particularly when using libraries.
const now = new Date();
const [year, month, day] = [now.getFullYear(), now.getMonth() + 1, now.getDate()];
console.log(`Today is ${day}/${month}/${year}`);
Removing a Property Without Mutation
Suppose you have an object representing a user, and you want to create a new object excluding the password field, leaving the original object unchanged.
const user = {
id: 1,
name: "Alice",
email: "alice@example.com",
password: "securepassword123",
};
// Destructure to exclude the password
const { password, ...userWithoutPassword } = user;
console.log(userWithoutPassword);
// Output: { id: 1, name: 'Alice', email: 'alice@example.com' }
console.log(user);
// Output: { id: 1, name: 'Alice', email: 'alice@example.com', password: 'securepassword123' }
Swapping variables
Destructuring allows swapping values without a temporary variable.
let x = 1, y = 2; [x, y] = [y, x]; console.log(x); // 2 console.log(y); // 1
Key Takeaways
In conclusion, JavaScript destructuring is a powerful tool for simplifying and streamlining your code, especially when working with complex objects and arrays. By mastering techniques like the binding and assignment patterns, omitting unused values, and using the rest parameter effectively, you can write cleaner, more efficient, and more maintainable code. Whether you’re dealing with large datasets or striving to make your code more readable, destructuring provides the flexibility and conciseness to achieve your goals.
Did you enjoy this article? If you found it helpful or have any questions, let us know in the comments below—we’d love to hear your thoughts!
Subscribe to my newsletter
Read articles from Abdullah Salaudeen directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
