deconstruction

Some of the new features introduced in ES6 are as follows:

Function foo(){return [1,2,3]} var TMP = foo(), a = TMP [0], b = TMP [1], c = TMP [2]; function foo(){return [1, 3]} var TMP = foo(), a = TMP [0], b = TMP [1], c = TMP [2]; console.log(a,b,c) //1 2 3Copy the code

We created a manual assignment from the values in the array returned by foo() to individual variables, a,b, and c. To do this we need the TMP variable. Of course we can also do this as objects:

function bar(){ return { x:4, y:5, z:6 } } var tmp = bar(), x = tmp.x, y = tmp.y, z = tmp.z; consolr.log(x,y,z); / / 4 5 6Copy the code

The property value tmp.x is assigned to the variable x, tnp.y through y and z.

Taking the value of an index from an array or a property from an object and assigning it manually can be considered structured assignment. ES6 adds a special syntax for destructuring, array destructuring and object destructuring, which eliminates the TMP variable and makes code cleaner.

var [ a, b, c ] = foo();

var { x: x, y: y, z: z } = bar() ;

console.log(a,b,c)   
//1 2 3
consolr.log(x,y,z)
// 4 5 6
Copy the code

Object attribute assignment mode

Let’s dive into the previous code segment {x: x,… } syntax. If the attribute name matches the name of the variable you want to declare, you can actually abbreviate this syntax:

var { x, y, z } = bar(); console.log(x , y , z); / / 4 5 6Copy the code

Cool!!!!

We’ve actually omitted the x: part. This may not seem like a very important detail, but why write longer forms when you can abbreviate them? Because the longer form allows you to assign an attribute to a different variable name, this is useful:

var { x :bam ,y: baz , z: bap } = bar();
console.log( bam , baz ,bap )// 4 5 6
console.log( x, y, z)
//ReferenceError: x is not defined
Copy the code

There is a subtle but super-important quirk to understand about this form of object deconstruction. To show why it might be a pit to watch out for, let’s consider how the normal object literal pattern is specified:

var X  = 10 , Y = 20;
var o = { a: X , b: Y };
console.log( o.a, o.b )
// 10 20
Copy the code

In {a: X, b: Y}, we know that A is the object property and X is the original value assigned to it. Its semantic schema is target: source, or attribute alias: value. We can see this intuitively because it is the same as = assignment, and its mode is target = source.

However, when you destruct an assignment with an object, it will look like the {.. } syntax is placed on the left hand side of the = operator —- you reverse the target: source pattern.

Think back:

var { x :bam ,y: baz , z: bap } = bar();
Copy the code

Here, the pattern facing the name is source: target (or value: attribute alias). X: BAM means that the attribute x is the source value and BAM is the assigned target variable. In other words, object literals are target <–source, and object destructions are source –>target. There’s another way of thinking about this syntax that might help ease the confusion. Consider the following code:

var aa = 10,bb=20;
var o = { x :aa ,y:bb };
var  { x:AA , y:BB } = o;
console.log(AA,BB)
// 10 20
Copy the code

X and y represent object properties in {x: aa,y :bb}, and x and y also represent object properties in {x: aa,y :bb}. In these two lines, if you erase the x: and y: sections in the code, leaving only aa, bb and aa, bb, its effect is conceptually impossible and will be to assign from AA to AA and from bb to bb. So this parallelism may help explain why syntactic patterns are deliberately reversed for this ES6 feature.

Not just a statement

So far, we’ve been using destruct assignment with var declarations (we can also use let and const, of course), but destruct is an assignment in general, not just a declaration.

var a, b, c, x, y, z;
[ a, b, c ] = foo();
( { x, y, z } = bar() );
console.log(a, b, c)
// 1 2 3
console.log(x, y, z)
//4 5 6
Copy the code

Variables can be already defined, and then deconstruction only takes care of the assignment, as we saw.

Note: Especially for object destructions, when we omit var, let, and const declarations, we must include the entire assignment expression in (), because otherwise the left hand side of the statement is the {.. } is treated as a block of statements rather than an object.

In fact, the variable expression (a, y, and so on) need not be a variable identifier. Any legal assignment expression is allowed. Such as:

var o = { }; [ o.a, o.b, o.c ] = foo(); ( { x:o.x, y:o.y, z:o.z } = bar() ); console.log(o.a, o.b, o.c) // 1 2 3 console.log(o.x, o.y, o.z ) // 4 5 6Copy the code

You can even use computed attribute names in destructions:

var whice = 'x',o = { } ;
( { [ whice  ] : o[ whice ] } = bar() )
console.log( o.x )
//4
Copy the code

The part of [whice]: is the computational attribute name, which results in x, the attribute that will be extracted from the current object as the source of the assignment.

The o[whice] part is just a plain object key reference, which is equivalent to O.x as a target for assignment.

It is also possible to create object maps/morphs using plain assignment:

var o1 = { a:1, b:2, c:3 },
o2 ={ };
( { a: o2.x, b:o2.y, c:o2.z } = o1 );
console.log( o2.x, o2.y, o2.z )
// 1 2 3
Copy the code

You can also map objects into an array:

var o1 = { a:1, b:2, c:3 },
o2 = [];
( { a: o2[0], b:o2[1], c:o2[2] } = o1 );
console.log( o2 )
// [ 1, 2, 3]
Copy the code

Or from the other direction:

var a1 = [ 1, 2, 3],
o2 = { };
[ o2.a, o2.b, o2.c ] = a1;
console.log( o2.a, o2.b, o2.c )
// 1 2 3 
Copy the code

You can also rearrange an array into another array

var a1 = [ 1, 2, 3 ],
a2 =[ ] ;
[ a2[2], a2[0], a2[1] ] = a1;
console.log( a2 )
// [  2, 3, 1 ]
Copy the code

You can also solve the traditional problem of swapping two variables without using temporary variables

var x = 10 ,
    y = 20;
[ y, x ] = [ x , y] ;
console.log( x,y )
// 20 10
Copy the code

Note: You cannot mix assignments with declarations unless you want all assigned expressions to be treated as declarations. Otherwise, you’ll get a syntax error;

Repeat the assignment

Object deconstruction allows source attributes (which hold any worth type) to be listed multiple times.

var { a: X , a: Y } = { a :1 }; X; // 1 Y; / / 1Copy the code

This can either deconstruct a subobject/array property or capture the value of the subobject/array itself

var { a: { x:X, x:Y }, a } = { a:{ x : 1} }; X ; //1 Y ; // 1 a; // { x : 1 }; ( { a : X, a : Y , a: [ Z ]} = { a:[ 1 ] } ); X.push( 2 ); Y[0] = 10; X; // [ 10 , 2 ] Y ; // [ 10 , 2 ] Z; / / 1Copy the code

Note: As we do now, all the deconstruction assignments are listed on one line, however, a much better note is to use appropriate indentation to scatter the deconstruction assignment pattern over multiple lines, much like we would write JSON or object literals — for readability. The goal of deconstruction is not less typing, but more readability of the statement.

Deconstruct the assignment expression

The completion value of an assignment expression with object or array deconstruction is the complete object/array value on the right-hand side.

var o = { a:1 , b:2 , c:3},
a,b,c,p;
p = { a, b, c } = o;
console.log(a, b, c)
// 1  2 3 
p === o  
// true
Copy the code

P is assigned as a reference to object O, not a, b, or c, as is array deconstruction:

var  o = [1 ,2 ,3 ]
,a,b,c,p;
p = [ a, b, c] = o;
console.log(a, b, c)
// 1  2 3 
p === o  
// true
Copy the code

By passing this object/array as the completion value, you can link together the destruct assignment expressions:

var o = { a:1 ,b :2 ,c: 3},
    p = [4, 5, 6],
    a,b,c,x,y,z;
( { a } = { b,c } = o );
[ x,y ] = [ z ] = p;
console.log(a,b,c)
// 1 2 3
console.log(x,y ,z)
//4 5 4
Copy the code

Too much, too little, just right?

For both array and object deconstruction assignments, you don’t have to allocate all the values that occur:

var [ , b ] = foo(); var { x, z} = bar(); console.log( b, x ,z); / / 2 4 6Copy the code

The values 1 and 3 returned from foo() are discarded, as is the value 5 returned from bar(). Similarly, if you try to assign more values than you are deconstructing/disassembling, they will quietly fall back to undefined as you would expect:

var [ ,,c,d ] = foo();
var { w,z } = bar();
console.log( c ,z )
// 3  6  
console.log( d, w )
//undefined undefined
Copy the code

This behavior follows in parallel the “undefined means missing” principle mentioned earlier

The default value is assigned

Both forms of deconstruction can provide default options for assignment, using a = syntax similar to the default function values discussed earlier.

Var [a= 3,b=6,c=9,d=12] = [1,2,3]; var { x= 5,y= 10, z= 15, w= 20 } = { x : 4, y:5, z:6 } console.log(a,b, c,d) // 1 2 3 12 console.log( x,y,z,w ) // 4 5 6 20Copy the code

It is also possible to combine default assignment with the assignment expression syntax described earlier:

var { x , y ,z ,w: WW= 20 } = bar();
console.log( x, y , z ,WW)
// 4 5 6 20
Copy the code

If you use an object or array as the default in a deconstruction, be careful not to confuse yourself.

var x = 200,
    y = 300 ,
    z =100;
var o1 = { x :{ y: 42 }, z: { y: z } };
( { y:x = { y: y } } = o1 );
( { z:y = { y: z } } = o1 );
( { x:z = { y: x } } = o1 );
console.log( x.y , y.y, z.y )
// 300 100 42
Copy the code

Caibaojian.com/es6/destruc ES6 document…

I hope this article will help you! This article is partially excerpted from ** JS you don’t understand **! Technical porter!

Let’s talk about structure assignment for ES6 (Advanced)