Object and array Destructuring makes it possible to declare
multiple variable identifiers and assign a value to each of them by unpacking the content of an array or object.
Structure of JavaScript Destructuring
let identifiersSide = valuesSide
Both sides could be arrays or both sides could be objects to achieve destructuring in JavaScript.
//Array
let [first, second, third] = ["Ola", "Ope", "Ayo"];
or
//Object
let {first, second, third} = {first:"Ola", second:"Ope", third:"Ayo"};
Array Destructuring Assignment.
Let's us deal with array-destructuring first.
Multiple Declarations and Assignments with Array Destructuring
Some years ago, before es6 became a common thing, any time I wanted to assign an element of an array or a property of an object as a value of a variable, I had to get each value one by one and assign them each as in:
let elements = ["Pizza", "$100", "2.5%"];
let name = elements[0]// Pizza
let price = elements[1]// $100
let discount = elements[2]// 2.5%
Do you see that?
I had to write everything one after another but with destructuring, we can achieve multiple variable declaration and assignment once as in:
let elements = ["Pizza", "$100", "2.5%"];
let [name, price, discount] = elements;
JavaScript engine will check both sides of the assignment and pair each of the elements on the left side with other corresponding elements on the right side. They are paired based on their corresponding positions ( 0th = 0th, 1st = 1st...) to form variables as in:
let elements = ["Pizza", "$100", "2.5%"];
let [name, price, discount] = elements;
// JS engine sees the above as
let name = "Pizza";
let price = "$100";
let discount = "2.5%"
Hey, wait!
What will happen if I reverse the above example?
let elements = [name, price, discount]; // VM144:1 Uncaught SyntaxError: Invalid destructuring assignment target
Do you see that error? It will throw an error if you do that.
Hey, wait!
Do you realize the variable names by the left are not quoted like a string?
They are not strings. They are treated as variable identifiers (name).
One to one destructuring:
This is when both sides of the assignment (name and value sides) have one element or property each as in:
//both sides have an element each
let [name] = ["Ayobami"];
//It is translated to:
let name = "Ayobami";
One-to-many destructuring:
This is when either of the sides of the assignment has an element or property and the other side has two or more elements or properties as in:
const [price] = ["$100", "Pizza"];
// The engine only picks the ones at the same position and ignore or skip the rest
console.log(price) // $100;
const [name, price, discount] = ["Pizza"];
console.log(name) // Pizza
console.log(price) // undefined
console.log(discount) // undefined
Many-to-many destructuring:
This is when both the left and the right sides of the assignment have two or more elements or properties each as in:
const [price, name] = ["$100", "Ayobami"];
console.log(price) // $100
console.log(name) // Ayobami
In short, the price which is the element at 0th position by the left side takes "$100" which is also an element at 0th position by the right side. The same thing happens to name and "Ayobami" too.
Using the Rest Operator (...) with Array Destructuring
The Rest Operator is used to group elements or properties into an array or object.
let queueAtMall = ["Ayobami", "Bush", "Obama", "Trump"];
How can we pack some of the elements of the array by the right side into a group with array destructuring?
This is how:
let [firstPerson,secondPerson,...theRest] = ["Ayobami", "Bush", "Obama", "Trump"];
console.log(firstPerson) // Ayobami
console.log(secondPerson)// Bush
console.log(theRest) // ["Obama", "Trump"];
We create variable "firstPerson" and assign it "Ayobami" and we do the same to "secondPerson" and assign it "Bush". The remaining elements in the array by the right side are grouped into an array and assigned them as the value of "theRest". Mind you, the rest (...) operator is used to pack the remaining elements into a new array.
Using the Spread Operator (...) with Array Destructuring
Sometimes, we need to add to existing elements of an array and assign them to some variable identifiers at the same time. Then, the spread operator (...) is needed.
let others = ["Ola", "Ayobami"];
let [snake, cat, tiger, leopard ] = ["Sussy", "Temi", ...others]
You can see that we add "Sussy", "Temi" and spread the elements of the array "others" in the new array and we now have:
let [snake, cat, tiger, leopard ] = ["Sussy", "Temi", "Ola", "Ayobami"]
Skipping Items in an Array for Destructuring
It is possible to ignore elements of an array as in:
let schools = ["Harvard", , , "Stanford"]//
console.log(schools[1]) // undefined
The skipped elements are replaced with "undefined". The same array feature can be used with array destructuring so that we can ignore some elements and make variables with others as in:
let schools = ["Great Ife", "Harvard", , , "Stanford"];
// pick the first and the last elements but skip the rest.
let [bestSchool, , , , contendingSchool] = schools;
console.log(bestSchool) // Great Ife.
console.log(contendingSchool) // Standford
let [,myChoice, , , myParentsChoice, ] = schools;
console.log(myChoice) // Harvard
console.log(myParentsChoice)// Stanford
In the above code, the first element is skipped on both sides. Only the second elements of both sides are picked. You should also notice that the second to the last element of the left array has the same position as the last element of the right array and that is why they are combined.
That is just like what we have been doing, the only difference is that we ignore some elements.
With the element skipping feature in an array, we can easily create multiple variables with destructuring and skip to the left or right to assign desired values to identifiers.
Setting Default Values in destructuring assignment
Once it is possible for some elements of an array to be ignored, we are sure that some elements may be undefined in arrays as in:
let friends = ["Obama", "Trump"];
let [childHoodFriend, schoolFriend, bestFriend] = friends;
console.log(bestFriend)// undefined.
Oops!
"bestFriend" is not defined because its corresponding position in the "friends" array is not defined. That is why it has the value of "undefined".
In that case, if it necessary to create a variable with a real value using destructuring, we have to set default values for the variables as in:
let friends = ["Obama", "Trump"];
let [
childHoodFriend = "Wahab",
schoolFriend = "Ola",
bestFriend = "No one unless stated"
] = friends;
console.log(bestFriend)// No one unless stated.
It is no longer "undefined" because it now has a default value just like others.
Swapping Elements in Destructuring Assignment
Destructuring assignment makes swapping values a breeze as we can easily rearrange elements' positions as in:
Let's declare and assign variables like before:
let five = 5;
let nine = 9;
Let's swap now:
[five, nine] = [nine, five];
console.log(five);//9
console.log(nine;//5
Yeah! We have swapped their values.
Array Destructuring Assignment with Functions
We can created multiple variables out of an array or object return by a function as in:
function friends() {
return ["Obama", "Trump" , "Buhari", "Ola"];
}
let [bestFriend,,, childHoodFriend] = friends();
console.log(bestFriend);//"Obama"
console.log(childHoodFriend);//"Ola"
It works.
Object Destructuring Assignment.
Unlike the array destructuring that uses position to map variable names and values, object destructuring uses keys to perform such operation.
Normally, destructuring enables us to make one or more variables out of an object or array easily. Without destructuring, this is how to create variables out of an object:
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let name = school.name;
let fee = school.fee;
let country = school.country;
Anyway, this how to do it with destructuring:
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let {name, fee, country} = school;
Destructuring makes it a bit easier.
Setting Default Variable Values
We can set a default variable value with object destructuring as in:
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let {name= "OAU", fee= "$20", country= "Nigeria", online= false} = school;
So the default values will be assigned in case no value is supplied through the assigned object's properties just like how no value is supplied for "online" in the above example.
Assigning a New Variable Name
There are some cases in which you may not want the names of the variables you are creating to be the property names of the object supplied. Then, you need to supply a new variable name for each of the object's properties as in:
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let {name: schoolName, fee:schoolFee, country:schoolLocation} = school;
console.log(schoolName)// Harvard
console.log(schoolFee)// $100
We can also set a default value for each of the the new variables as in:
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let {name:schoolName="OAU", fee:schoolFee = "$20", country:schoolCountry = "Nigeria", online:schoolOnline=false} = school;
console.log(schoolName)// Harvard
console.log(schoolOnline)// false
Declaring a variable before assigning value to it with destructuring
It is possible to declare some variables and then assign values to them later with object destructuring.
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let name, fee, country;
( {name, fee, country} = school );
console.log(name)// Harvard
console.log(fee)// $100
In the above example, we declared three variables without assigning values to them immediately. We assign values to each of them later by destructuring an object (school) but you have to pay attention to the fact that we wrap the entire expression in a bracket ( ) as in:
( {name, fee, country} = school );
Destructuring a Nested Object
A nested object can also be destructured as in:
let dev = {
name: "Codingnninja",
fee: "$100",
country: "Nigeria",
contacts: {
email: "ayobami.dev@yahoo.com",
phone: "+23490897976847448"
}
};
let {
name:nickname,
fee: charge,
country: residentCountry,
contacts: {
email : devEmail,
phone : devPhone}
} = dev;
console.log(devEmail);// ayobami.dev@yahoo.com
console.log(devPhone);// +23490897976847448
Our focus here is to destructure the nested object and we have destructured "contacts" which is nested in "dev". So, logging both devEmail and devPhone in the console now yield "ayobami.dev@yahoo.com" and "+23490897976847448" respectively.
Using the rest operator in Object Destructuring
The rest parameter can be used to pack remaining arguments or values into an object as in:
let dev = {
name: "Codingnninja",
fee: "$100",
country: "Ghana",
contacts: {
email: "ayobami.dev@yahoo.com",
phone: "+23490897976847448"
}
};
let {name, fee, ...theRest} = dev;
console.log(theRest);// {conuntry: "Nigeria", contacts: { email: "ayobami.dev@yahoo.com", phone: "+23490897976847448" }
}
The Rest operator packs the remaining unlisted "key and value" pairs into an object.
Object Destructuring as a parameter
Sometimes when we are expecting an object to be passed to a function as a parameter, using destructuring can help us define the identifies we are expecting as in:
function school({fee: schoolFee, place: address} = {}) {
console.log(schoolFee);
console.log(address);
}
school() // undefined
school(['$100'])// undefined
school({fee:'$100'}); // $100
In the above examples, we are expecting an object that contains "fee" and "place" as its properties. Then, we will pick the values of such properties once they are available. Anyway, calling the function with a non-object argument may force JavaScript to throw an exception.
Let's set default values for our expected parameters as in:
// Give school parameters a default value each
function school({fee: schoolFee= "$100", place: address = "US"} = {}) {
console.log(schoolFee);
console.log(address);
}
school() // $100, US
school(['$100'])// // $100, US
school({fee:'$20'}); // $20, US
Also, we set default values for our expected parameters. In the above example, if we get no parameter, the default values will be available for the identifiers in the function. Anyway, calling the function with a non-object argument may force JavaScript to throw and exception.
Object Destructuring with Computed Property Names
It is possible to create or access an object property with a square bracket [] as in:
let student = {["name"]:"Ayobami"};
student.name // Ayobami
student["name"] // Ayobami
The square bracket makes it possible to create objects dynamically.
Here, we are going to use it for destructuring as in:
let firstProperty = "name";
let secondProperty = "fee";
let school = {
name: "Harvard",
fee: "$100",
country: "USA"
}
let {[firstProperty] : schoolName, [secondProperty]: schoolFee} = school;
console.log(firstProperty) // name;
console.log(schoolName) // Harvard
Yeah! We have computed the object's properties with the square braces and assign a corresponding value to it from another object named "school";
Hurry!
Destructuring in JavaScript makes creating multiple variables out of an array or object easy.
Mind you, every feature of an object or array we used in explaining destructuring can be used without destructuring.
See you in the next lesson.
One more thing
Are you having difficulties to learn and understand JavaScript and build projects with it? JavaScript for a Total Novice teaches JavaScript and Project Making Fundamentals with simple illustrations and examples that make everything so easy. You can now handle any difficult projects without fear.
Don't trust me, get a free previous to judge by yourself: https://bit.ly/3o3TMyg
Related Write-ups:
Top comments (3)
Hi,
I stumbled upon a preview of your post you posted on twitter, containing your header image.
The line
should be
The
compose
utility reduces functions from right to left, otherwise, it's called apipe
😉.Added quotation mark for Trump in the example just in case you haven't seen the typo. [
firstPerson,secondPerson,...theRest] = ["Ayobami", "Bush", "Obama", "Trump"];
console.log(firstPerson) // Ayobami
console.log(secondPerson)// Bush
console.log(theRest) // ["Obama", "Trump"]
Wow! Thanks for spotting the typo. I just fixed it.