JavaScript destructuring
Tags: javascript, webdev
Published: 2020-04-18 03:45:54

##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
<pre>
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' }
</pre>
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.
<pre>
let a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
</pre>
#####We can relinquish(omit) the unnecessary values from the array while destructuring it.
<pre>
let [x, , y, , , z] = [1, 2, 3, 4, 5, 6];
console.log(x); // 1
console.log(y); // 3
console.log(y); // 6
</pre>
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
<pre>
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 ]
</pre>
Always consider the rest operator as the last element while unpacking the values from source variable.
#####Use as a swapper
<pre>
let a = 1, b = 2;

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

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

console.log(x); //  first
console.log(y); // second
</pre>
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.
<pre>
let { a = 10, b = 20, x = 30} = {a: "first", b: "second"};

console.log(a); //  first
console.log(b); //  second
console.log(x); //  30
</pre>
#####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.
<pre>
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
</pre>
#####Nested object destructuring 
<pre>
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.
</pre>
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?
<pre>
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.
</pre>
#####Destructuring with default values
<pre>
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.
</pre>
#####Computed Object property names and destructuring
<pre>
const key = 'grapes';
let {[key]: fruit} = { grapes: 'A small, round, smooth-skinned edible fruit.' }

console.log(fruit)  //  A small, round, smooth-skinned edible fruit.
</pre>
#####Rest in Object destructuring
Consider ___rest___ operator as the last element while unpacking the values from the source element.
<pre>
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' }
</pre>
#####Invalid identifier as a property name
___Space___, ___dash___ and ___special character___ are not allowed for Object's property name.
<pre>
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.
</pre>
#####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.
<pre>
const obj = { property: 123 };
obj.__proto__.anotherProto = 456;
let { anotherProto } = obj

console.log(anotherProto);  // 456
</pre>