Destructuring Assignment

Let’s say, you are moving in to a new house. Once you moved, you need to unpack the items. The plate goes to kitchen items, the cloth goes to wardrobe and the shoes go to shoe rack.

Destructuring does the same thing for us. If we want to unpack few items from an array or object, destructuring makes it easier for us.

Array Destructuring

Previously when we wanted to pull out elements from array the syntax was

let itemsBox = ['plates', 'clothes', 'shoes'] 

let kitchen = itemsBox[0]
let wardrobe = itemsBox[1]
let shoeRack = itemsBox[2]

After using destructuring

let itemsBox = ['plates', 'clothes', 'shoes'] 

let [kitchen, wardrobe, shoeRack] = itemsBox

console.log(kitchen)  // plates
console.log(wardrobe) // clothes
console.log(shoeRack) // shoes

Note: Destructuring does not mutate the original array or object.

In above example, we have used array literal syntax to the left of the assignment operator.

If you decide not to take out wardrobe items for now, you can just avoid it like this

let [kitchen, , shoeRack] = itemsBox

Why is destructuring useful?

In ES5 and earlier, fetching data from arrays and objects were leading to a lot of duplicate code. Even to get data into a local variables from nested objects you need to dig through the entire structure. Destructuring provides simple looking syntax. Apart from that it has many more benefits like swapping data and parsing return values from function is much easier using destructuring.

Note: You must provide an initializer when using destructuring with var, let, const.

Swapping using destructuring

let item1 = 10
let item2 = 20

[item1, item2] = [item2, item1] 

console.log(item1) // 20
console.log(item2) // 10

Parsing returned array values from a function

function calculate(a, b) {
   let add = a + b
   let subtract = a - b
   return [add, subtract]
}

let [sum, difference] = calculate(20, 10)
console.log(sum, difference) // 30 10

Default values

If an array elements are less than the number of variables to the left side of the assignment operator, the remaining variables are considered as undefined.

We can assign default values to the variables to avoid being undefined.

let [a, b, c=5] = [1, 2]

console.log(a) //1
console.log(b) //2
console.log(c) //5

Nested array destructuring

We can descend the nested array by providing the same structure to the left of the assignment operator as to the right.

let hungryHippo = ['pizza', 'burger', ['chocolate', 'icecream'], 'noodles']

let [lunch, dinner, [sweet], snacks] = hungryHippo

console.log(lunch) // pizza
console.log(dinner) // burger
console.log(sweet) // chocolate
console.log(snacks) // noodles

Destructing with rest(…)

If we want to assign the remaining items of an array to a variable, the … syntax is used.

let itemsBox = ['plates', 'clothes', 'shoes', 'books', 'pencils', 'papers']

let [kitchen, wardrobe, shoeRack, ...stationary] = itemsBox 

console.log(kitchen)  // plates
console.log(wardrobe) // clothes
console.log(shoeRack) // shoes

console.log(stationary) // ['books', 'pencils', 'papers']

This technique is even used to create a clone of an array.

let [...allItems] = itemsBox

console.log(allItems) // ['plates', 'clothes', 'shoes', 'books', 'pencils', 'papers']

Note: The rest variable must be at last. Rest variable if followed by comma, will throw an error.

Object Destructuring

Object destructuring uses the object literal to the left side of the assignment operator.

let person = {
   name: 'John',
   age: 25
}

let {name, age} = person

console.log(name) //John
console.log(age) //25

In the above example, person.name is stored in variable name and person.age is stored in variable age.

Note: Variable declaration using const always needs initialization but even when we use var or let for object destructuring, it is must to initialize or it will throw an error.

const {name, age} // error

var {name, age} // error

let {name, age} //error

We can make assignment separate from declaration like this:

let person = {
   name: 'John',
   age: 25
}

let name, age

({name, age} = person)

Note: ( ) is must around destructuring assignment statement. The reason is, curly braces are considered as a block in JavaScript. Parenthesis interprets it as an expression.

Order does not matter in object destructuring.

let person = {
   name: 'John',
   age: 25
}

let {age, name} = person

console.log(age) //25
console.log(name) // John

Assigning different variable names

If we feel to use different variable names, we can do it like this:

let person = {
	name: 'John',
	age: 25
}

let {name: firstName, age: howOld} = person

console.log(firstName) //John
console.log(howOld) //25

In above example, person.name is assigned to firstName and person.age is assigned to howOld. It is opposite to the regular object syntax. In the regular syntax the key is on the left of the colon and value is on the right. In this case the value is on the left of the colon and key or name is on the right.

Default values

We can give even default values to the variables. If we don’t assign default values and the variable is not available in the object, it will automatically be trated as undefined.

let person = {
   name: 'John',
   age: 25
}

let {name, age, gender='male', speaks:language = 'English', somethingElse} = person

console.log(gender) //male
console.log(language) //English
console.log(somethingElse) //undefined

Nested destructuring

Nested destructuring helps to unpack only those information which we want from deep inside the object.

let person = {
   name: 'John',
   age: 25,
   address: {
      street: '4th street',
      city: 'New York'
   }
}

let {address:{city}} = person

console.log(city) //New York

The curly braces to the right side of the colon indicates that the destination is one more level deep into the object.

Destructuring with rest(…)

It is much similar to array destructuring with rest.

let person = {
   name: 'John',
   age: 25,
   qualification: 'Engineer'
}

let {name, ...otherInfo} = person

console.log(otherInfo.age) // 25
console.log(otherInfo.qualification) //Engineer
console.log(otherInfo) // { age: 25, qualification: "Engineer" }

In the above example, otherInfo will behave like an object with remaining properties and values from the person object.

Array and object mixed destructuring

We can easily destructure more complex mixture of array and object together. It is very useful when we have a JSON structure.

let colors = {
   favorite: 'Pink',
   chart: {
      primary: ['Red', 'Yellow', 'Blue'],
      secondary: ['Purple', 'Green', 'Orange']
   }
}

let {favorite, chart: {secondary:[first, ...others]}} = colors

console.log(favorite) // Pink
console.log(first) //Purple
console.log(others) // ['Green', 'Orange']

Object dstructuring as function parameters

let person = {
   name: 'John',
   age: 25
} 

function getInfo({name, age}) {
   return `${name} is ${age} years old.`
}

console.log(getInfo(person)) // John is 25 years old.

One more use of object destructuring is, we can pass optional parameters in function arguments.

function draw(shape, {width, length, radius}) {
   // code to draw a shape	
   console.log(shape, width, length, radius)
}  

draw('circle', {radius: 5}) // length and width are set to undefined

draw('square', {width: 10}) // length and radius are set to undefined

If the destructured parameters are not passed, they will be undefined.

Note: In above kind of function, function calling time, if we don’t pass the second argument, it will throw an error. It is because internally JavaScript engine does like this

function draw(shape, options) {
   let {width, length, radius} = options
}

If the right side of an assignment operator is not passed it will evaluate as undefined and throws an error.

draw('rectangle') // throws an error

To avoid it we can set default value for second argument.

function draw(shape, {width, length, radius} = {}) {
   // code to draw a shape	
}

Now all the optional variables will be undefined. Even if the second argument is not passed, it will not throw any error.

Let’s summarize

  • Using destructuring, it is very convenient to pull out required elements or items from an array and an object.
  • To extract array data, array pattern is used and to extract object data, object pattern is used.
  • In both array and object destructuring, default values can be assigned.
  • In both destructuring, if right side of the assignment operator is undefined, it will throw an error.
  • Destructuring declaration using var, let or const to create variable must need initializer.
  • Destructuring is very useful in functions where optional parameters are used.
Subscribe
Notify of

0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments