DEV Community

Cover image for A Simple Guide to Javascript Destructuring
Ayobami Ogundiran
Ayobami Ogundiran

Posted on • Updated on

A Simple Guide to Javascript Destructuring

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
Enter fullscreen mode Exit fullscreen mode

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"};
Enter fullscreen mode Exit fullscreen mode

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% 
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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%"
Enter fullscreen mode Exit fullscreen mode

Hey, wait!

What will happen if I reverse the above example?

let elements = [name, price, discount]; // VM144:1 Uncaught SyntaxError: Invalid destructuring assignment target
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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"];
Enter fullscreen mode Exit fullscreen mode

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"];
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Let's swap now:

[five, nine] = [nine, five];

console.log(five);//9
console.log(nine;//5
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Anyway, this how to do it with destructuring:

let school = {
   name: "Harvard",
   fee: "$100",
   country: "USA"
}
let {name, fee, country} = school;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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   );
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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" }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

  1. How to Use Array and Object Destructuring in JavaScript by @sarah_chima

  2. Destructuring assignment by MDN

Discussion (3)

Collapse
topheman profile image
Tophe

Hi,

I stumbled upon a preview of your post you posted on twitter, containing your header image.

The line

const compose = (...fns) => res => fns.reduce((accum, next) => next(accum), res)
Enter fullscreen mode Exit fullscreen mode

should be

const compose = (...fns) => res => fns.reduceRight((accum, next) => next(accum), res)
Enter fullscreen mode Exit fullscreen mode

The compose utility reduces functions from right to left, otherwise, it's called a pipe πŸ˜‰.

Collapse
davidyaonz profile image
David Yao

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"]

Collapse
codingnninja profile image
Ayobami Ogundiran Author

Wow! Thanks for spotting the typo. I just fixed it.