DEV Community

Cover image for JavaScript destructuring
Kaushal
Kaushal

Posted on • Updated on

JavaScript destructuring

Introduction

JavaScript ES6 comes with the destructuring assignments. A name define its use, destructure values from an array and properties from an object. For instance,

Syntax

let x, y, rest;
[x, y] = [1, 2];

console.log(a); //  1
console.log(b); //  2

[x, y, ...rest] = [1, 2, 3, 4, 5];

console.log(x); //  1
console.log(y); //  2
console.log(rest); //  [3,4,5]

({ a, b, ...c } = {a: "first", b: "second", c: "third", d: "fourth", e: "fifth"});

console.log(a); //  first
console.log(b); //  second
consoel.log(c); //  { c: 'third', d: 'fourth', e: 'fifth' }

The destructuring assignment uses syntax, on the left side of the equal sign, is assignment of the values from the sourced variable, source is on the right side of the equal sign.

Array destructuring

Assignment is allowed separate from declaration.
let a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
We can relinquish(omit) the unnecessary values from the array while destructuring it.
let [x, , y, , , z] = [1, 2, 3, 4, 5, 6];
console.log(x); // 1
console.log(y); // 3
console.log(y); // 6

A single comma (,) can seek one position forward. The common can be one or more in the destructuring list as we want to skip the values.

Rest element must be last element
let [a, , ...b, c] = [1, 2, 3, 4, 5, 6];  // ___give error___
// SyntaxError: Rest element must be last element

let [a, , , ...b] = [1, 2, 3, 4, 5, 6];

console.log(a); //  1
console.log(b); // [ 4, 5, 6 ]

Always consider the rest operator as the last element while unpacking the values from source variable.

Use as a swapper
let a = 1, b = 2;

[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1

Object destructuring

Declaration and assignment
let a, b;
{ a, b } = {a: "first", b: "second"};
console.log(a); //  first
console.log(b); // second
Assigning with new name(rename)
let { a: x, b: y} = {a: "first", b: "second"};

console.log(x); //  first
console.log(y); // second

Here, it will take a and b from the object and assign it to newly named local variable x and y.

Default value

In some cases we want to pull out a value from object, only if, it's exist in it,
if not, set a default value rather than just holding an undefined in the variable.

let { a = 10, b = 20, x = 30} = {a: "first", b: "second"};

console.log(a); //  first
console.log(b); //  second
console.log(x); //  30
Default value to newly define local variable

Unpack the value from object and assigned to a variable with a different name and default value, if property not exist in the object.

let { a: xx = 10, b: yy = 20, x = 30} = {a: "first", b: "second"};

console.log(xx); //  first
console.log(yy); //  second
console.log(x); //  30
Nested object destructuring
const fruit = {
  seed: {
    countable: 'A fertilized grain, initially encased in a fruit, which may grow into a mature plant.' ,
    botany: 'A fertilized ovule, containing an embryonic plant.',
    uncountable: 'An amount of fertilized grain that cannot be readily counted.'
  },
  definition: 'All produce that contains seeds is botanically classified as a fruit.',
}

let { countable, definition } = fruit;

console.log(countable);  //  undefined
console.log(definition);  //  All produce that contains seeds is botanically classified as fruit.

See, a variable countable is printed as undefined, because the countable is define with in seed object, which is nested object. Thus, the question is how to destructuring these kinds of objects?

const fruit = {
  seed : {
    countable: 'A fertilized grain, initially encased in a fruit, which may grow into a mature plant.' ,
    botany: 'A fertilized ovule, containing an embryonic plant.',
    uncountable: 'An amount of fertilized grain that cannot be readily counted.'
  },
  definition: 'All produce that contains seeds is botanically classified as a fruit.',
}

let { seed: { countable, botany }, definition } = fruit;

console.log(countable);  //  A fertilized grain, initially encased in a fruit, which may grow...
console.log(botany);  //  A fertilized ovule, containing an embryonic plant.
console.log(definition);  //  All produce that contains seeds is botanically classified as a fruit.
Destructuring with default values
const fruit = {
  seed : {
    countable: 'A fertilized grain, initially encased in a fruit, which may grow into a mature plant.' ,
    botany: 'A fertilized ovule, containing an embryonic plant.',
    uncountable: 'An amount of fertilized grain that cannot be readily counted.'
  },
  definition: 'All produce that contains seeds is botanically classified as fruit.',
}

let { seed: { botany }, definition, sweet = 'Containing a sweetening ingredient.' } = fruit;

console.log(botany);  //  A fertilized ovule, containing an embryonic plant.
console.log(definition);  //  All produce that contains seeds is botanically classified as fruit.
console.log(sweet);  //  Containing a sweetening ingredient.
Computed Object property names and destructuring
const key = 'grapes';
let {[key]: fruit} = { grapes: 'A small, round, smooth-skinned edible fruit.' }

console.log(fruit)  //  A small, round, smooth-skinned edible fruit.
Rest in Object destructuring

Consider rest operator as the last element while unpacking the values from the source element.

let { a, b, ...res } = {a: "first", b: "second", c: "third", d: "fourth", e: "fifth"};

console.log(a); //  first
console.log(b); //  second
console.log(res); //  { c: 'third', d: 'fourth', e: 'fifth' }
Invalid identifier as a property name

Space, dash and special character are not allowed for Object's property name.

let { 'of a person' } = {'of a person': 'Having considerable flesh.'};  //  cannot access property 
let { 'of a person': seed } = {'of a person': 'Having considerable flesh.'}; 
//  we have to rename it for access the value

console.log(seed); //  Having considerable flesh.
The prototype chain is looked up when the object is deconstructed

When deconstructing an object, if a property currently exists not accessed in itself, it will continue to look up along the prototype chain.

const obj = { property: 123 };
obj.__proto__.anotherProto = 456;
let { anotherProto } = obj

console.log(anotherProto);  // 456

Top comments (0)