What is Destructuring in JavaScript?

Destrucutring is a way by which we extract values from arrays and properties from objects and assign it to individual variable. When extracting values you can either choose to extract single or multiple values.

What is Array Destructuring in JavaScript?

First, let’s see the example of how elements of array are assigned to variables in ES5.

const fruits = ['banana','apple','orange', 'water melon','mango'];

const fruit1 = fruits[0];

const fruit2 = fruits[1];

const fruit3 = fruits[2];

console.log(fruit1);
// banana

console.log(fruit2);
// apple

console.log(fruit3);
// orange

Here we are specifying array indexes ( fruits[0], fruits[1], fruits[2] ) and setting it to variables fruit1,fruit2 and fruit3 respectively.

Now let’s rewrite the code with destructuring syntax.

const fruits = [‘banana’,’apple’,’orange’, ‘water melon’,’mango’];

const [

fruit1,

fruit2,

fruit3

         ] = fruits;

const fruits = ['banana','apple','orange', 'water melon','mango'];

const [

fruit1,
fruit2,
fruit3

        ] = fruits;

You can also write it in a single line. It is best practice to write in multiple lines if there are large number of variables for better readability.

const [ fruit1, fruit2,fruit3 ] = fruits;

console.log(fruit1);
// banana

console.log(fruit2);
// apple

console.log(fruit3);
// orange

As you can see destructuring helps us write code in more concise way.

It is important to remember that  [ fruit1, fruit2,fruit3 ] is not an array. This is because it is on the left hand side of a equal sign.

It is in fact a pattern for destructuring.

We are assigning value of first index array item to first variable(fruit1), value of second index array item to second variable (fruit2) and third index value to third variable (fruit3).

Any array item that have no variables to assign are just ignored.

In our example above, index 3 (water melon) and index 4 (mango) of fruits array are ignored.

Default Values

What if we have more variables than array elements?

const fruits = [ 'banana', 'apple'];

const [ fruit1, fruit2, fruit3  ] =  fruits;

console.log(fruit1);
// banana

console.log(fruit2);
// apple

console.log(fruit3);
// undefined

If we destructure array and tried to unpack value of array index that does not exist, we get undefined.

Similarly if array index exist but does not have any value then we will get undefined.

const fruits = ['banana',,'orange'];

const [

fruit1,
fruit2,
fruit3

] =  fruits;

console.log(fruit1);
// banana

console.log(fruit2);
// undefined

console.log(fruit3);
// orange

If you don’t want undefined value then you can assign default value to variable.

const fruits = ['banana','apple'];

const [

fruit1,
fruit2,
fruit3 = 'mango'

    ] =  fruits;

console.log(fruit3);
// mango

Rest Operator

In above example we ignored array items that we didn’t need. But we can also collect those array items as an array and assign it to variable. This is done with rest operator.

This can also be helpful if you don’t know the number of items in array.

const fruits = ['banana', 'apple', 'orange', 'water melon', 'mango'];

const [

fruit1,
fruit2,
…fruit3

] =  fruits;

console.log(fruit1);
// banana

console.log(fruit2);
// apple

console.log(fruit3);
// [ ‘orange’, ‘water melon’, ‘mango’ ]

You should always use rest operator on last variable otherwise you will get syntax error.

const [

fruit1,
…fruit2,
fruit3

] =  fruits;

// SyntaxError: Rest element must be last element

Skipping Values

When you destructure array, you may not need all the values. For example if you only need values of first and third array index then you can skip second index value. If you need you can skip more than one values too.

const fruits = ['banana','apple','orange'];

const [

fruit1,

  ,

fruit3

] =  fruits;

console.log(fruit1);
// banana

console.log(fruit3);
// orange

/* Skipping multiple values */

const fruits = ['banana','apple','orange', 'water melon','mango'];

const [

  ,

  ,

  ,

  ,

fruit1

] =  fruits;

console.log(fruit1);
// mango

Nested Array Destructuring

const fruits = ['banana',['apple','orange'],'mango'];

const [

fruit1,

  [fruit2a, fruit2b],

  fruit3

      ] =  fruits;

console.log(fruit1);
// banana

console.log(fruit2a);
// apple

console.log(fruit2b);
// orange

console.log(fruit3);
// mango

Here in our code example, we have nested array at second index of fruits array. To destructure nested array we should assign it to another destructuring pattern instead of variable identifier.

Swap values

Destructing pattern makes swapping values very easy.

let x = 1;

let y = 2;

[x, y] = [y , x]

console.log(x);
// 2

console.log(y);
// 1

What is object destructuring?

In object destructuring we unpack properties from object and assign it to individual variable. Unlike array destructuring where position of index matter, in object destructuring order of variables do not matter.

const fruits = {

  fruit1: "apple",
  fruit2: "banana",
  fruit3: "orange",

}

const {

fruit3,

fruit1,

fruit2

} = fruits;

console.log(fruit1);
// apple

console.log(fruit2);
// banana

console.log(fruit3);
// orange

Here in our example above, value of fruit1 property of fruits object is assigned to variable fruit1. Similarly value of property fruit2 is assigned to variable fruit2 and value of property fruit3 is assigned to variable fruit3. Name of variables and property key name must be same otherwise variable will be set to undefined value.

In object destructuring, you can also give variables a different name.

const fruits = {

fruit1: "apple",
fruit2: "banana",
fruit3: "orange",

};

const {

fruit1:a,
fruit2: b

} = fruits;

console.log(a);
// apple

console.log(b);
// banana

Here property fruit1 value is assigned to variable a and property fruit2 value is assigned to variable b.

If you have source and target variable with same name.

const fruits = {

fruit1: "apple",
fruit2: "banana",
fruit3: "orange"

}

const {

fruit1:fruit1,
fruit2:fruit2,
fruit3:fruit3

} = fruits;

You you can refactor the code like this.

const {

  fruit1,
  fruit2,
  fruit3

} = fruits ;

console.log(fruit1);
// apple

console.log(fruit2);
// banana

console.log(fruit3);
// orange

Default Value

const fruits = {

fruit1: "apple",
fruit2: "banana",
fruit3: "orange",

};

const {

fruit1,
fruit4 

} = fruits;

console.log(fruit1);
// apple

console.log(fruit4);
// undefined

Here console logging fruit4 variable gives us undefined because fruits object does not have property name fruit4. As stated above when you declare variable, the name of variable must exist in object as property key name.

Like array destructuring, you can assign default value to variable if you don’t want undefined value.

const fruits = {

fruit1: "apple",
fruit2: "banana",

};

const {

fruit1,
fruit4 = "orange"

} = fruits;

console.log(fruit1);
// apple

console.log(fruit4);
// orange

Rest Operator

const fruits = {

fruit1: "apple",
fruit2: "banana",
fruit3: "orange"

};

const {

fruit1,
…fruit

} = fruits;

console.log(fruit1);
// apple

console.log(fruit);
// { fruit2: ‘banana’, fruit3: ‘orange’ }

We can use rest syntax to collect remaining properties to a variable after we unpacked the property name we want. This is similar to how we used rest operator in array destructuring.

Here in our code example, we extracted fruit1 property of fruits object and saved rest of the properties to variable fruit.

Nested Object Destructuring

const fruits = {

fruit1: "apple",

fruit2: {

fruit2a:"banana",
fruit2b: "orange"

},

fruit3: "mango"

};

const {

fruit1,

fruit2:{

fruit2a,

fruit2b

}

} = fruits;

console.log(fruit1);
// apple

console.log(fruit2a);
// banana

console.log(fruit2b);
// orange

Here we have fruits object with sub object fruit2. When we destructure nested object, we need to assign it to another inner destructuring pattern to unpack properties of nested object.

Parameter Destructuring

const fruits = {

fruit1: "apple",
fruit2:"banana",
fruit3: "mango"

};

function bestFruit(fruits){
  const {
    fruit1,
    fruit2,
    fruit3
  } = fruits;
  return `My favourite fruit is ${fruit3}`
}

bestFruit(fruits);
// My favourite fruit is mango

Here we have a function that accepts object as a parameter and we are destructuring it inside the function definition.

But instead of destructuring inside function we can also destructure object at parameter position.

function bestFruit({fruit1,fruit2,fruit3}){
  return `My favourite fruit is ${fruit3}`
}

bestFruit(fruits);
// My favourite fruit is mango.

We can also just get the value we need. No need to unpack all the properties of object.

const fruits = {

fruit1: "apple",
fruit2:"banana",
fruit3: "mango"

}

function bestFruit({fruit3}){
  return `My favourite fruit is ${fruit3}`
}

bestFruit(fruits);
// My favourite fruit is mango.

Similarly you can also destructure array at parameter position.

const fruits = ['apple','banana','mango'];

function bestFruit([fruit1, fruit2, fruit3]){
  return `My favourite fruit is ${fruit3}`
}

bestFruit(fruits);
// My favourite fruit is mango