ES6 learn Chapter 2 deconstruction and assignment of variables

Posted by Eclipse on Wed, 24 Nov 2021 03:07:16 +0100

preface

This note is the second deconstruction and assignment of variables.
Link to the original text of this chapter: Deconstruction and assignment of variables

Destructuring assignment

ES6 allows you to extract values from arrays and objects and assign values to variables according to a certain pattern, which is called deconstructing.

Deconstruction assignment is an extension of the assignment operator.
This is a method of pattern matching for arrays or objects, and then assigning values to variables in them.
The code is concise and easy to read, and the semantics is clearer; It also facilitates the acquisition of data fields in complex objects.

Deconstruction assignment of array

Assign values to variables.

let sample1 = 1;
let sample2 = 2;
let sample3 = 3;

The above code uses the array deconstruction assignment of ES6, which can be written as follows. Extract the value from the array and assign a value to the variable according to the corresponding position.

let [sample1, sample2, sample3] = [1, 2, 3]; 
console.log(sample1, sample2, sample3); // 1, 2, 3

This writing belongs to "pattern matching". As long as the patterns on both sides of the equal sign are the same, the variables on the left will be given corresponding values.
The above code assigns values while declaring variables. ES6 can also declare variables first and then deconstruct and assign values,

let sample1, sample2, sample3;  // First statement
[sample1, sample2, sample3] = [1, 2, 3];
console.log(sample1, sample2, sample3);  // 1, 2, 3

Array deconstruction

There are several situations

  • Successful deconstruction

    • Complete deconstruction assignment
    • Incomplete deconstruction assignment
    • Nested array deconstruction assignment
    • Variable declaration and assignment deconstruction
    • Declare variables before deconstruction and assignment
  • Unsuccessful deconstruction

be careful:

  • The right side of the array form deconstruction assignment equal sign must be a traversable structure, that is, a data structure with Iterator interface.
  • The deconstruction assignment in the form of array needs to assign a value to the object according to the corresponding position.
  • Array form deconstruction assignment failed. The value of the variable is equal to undefined.
  • The array of deconstruction assignment in the form of array can be multi-dimensional array.
  • Array form deconstruction assignment does not need to deconstruct all the arrays to the right of the equal sign.
  • Array form deconstruction assignment allows the patterns on the left of the equal sign not to all match the arrays on the right of the equal sign.
// Deconstruction successful
let [sample1, [sample2, sample3]] = [1, [2, 3]]; 
console.log(sample1, sample2, sample3); // 1, 2, 3

// If the deconstruction fails, the value of the variable is equal to undefined.
let [sample] = []; // The value of sample is undefined 
let [sample1, sample2] = [1]; // The value of sample2 is undefined 

// If the right side of the equal sign is not an array, that is, a non ergodic structure, an error will be reported
let [sample] = 1;  // An error is reported directly because the value to the right of the equal sign is a literal and cannot be traversed
let sample1, sample2, sample3, sampleN;  // Declare variables before deconstruction and assignment
[[sample1, sample2], sample3, ...sampleN] = [[1, 2], 3, 4, 5]; // Nested Array 
console.log(sample1, sample2, sample3, sampleN); // 1 2 3 [4, 5]

let [sample11, sample12] = [1, 2, 3]; // Variable declaration and assignment deconstruction
let [sample21, ,sample23] = [1, 2, 3];
console.log(sample11, sample12); // Incomplete deconstruction 1 2
console.log(sample21, sample23); // Incomplete deconstruction 1 3

Default value

When the value you don't want to deconstruct from the array is undefined, the deconstruction assignment allows you to specify the default value.

be careful:

  • When an array member is strictly equal to undefined, the default value will take effect.
  • The default value is not necessarily literal, and other variables assigned by deconstruction can also be referenced, but the variable must be declared.
  • The default value is an expression, which is evaluated lazily, that is, it will be evaluated only when it is used.
// When the value does not exist, the default value takes effect
let [sample1 = 10, sample2 = 11] = [2];
console.log(sample1, sample2); // 2 11 

// The default value takes effect only when the value = = = undefined
let [sample10 = 10, sample11 = 11, sample13 = 12] = [undefined, "", null];
console.log(sample10, sample11, sample13); // 10, , null, 

let [sample21 = 1, sample22 = sample21] = [];
console.log(sample21, sample22);
let sample30 = 31;
let [sample31 = sample30, sample32 = 3] = [];
console.log(sample31, sample32);

Deconstruction assignment of object

Object deconstruction

The deconstruction assignment of an array is very different from that of an object

be careful:

  • The deconstruction assignment of an object is no longer related to the order, but to the variable name. The variable must have the same name as the attribute in order to get the correct value.
  • The deconstruction assignment of an object is matched according to the key value of the object.
  • If the deconstruction is unsuccessful, the value is undefined.
  • Like array deconstruction assignment, objects with nested structures can be deconstructed and assigned.

The left and right sides of the expression equal sign must have mutually matched attribute values, so that the value value of the successfully matched key on the right can be assigned to the value of the corresponding key on the left, and the value on the left can be used as a variable.

let { sample: sample, sample1: sample2 } = { sample: 10, sample1: 11 }
console.log(sample); // 10
console.log(sample1) // Error sample1 is not defined
console.log(sample2) // 11

ES6 extends the object. The attribute and value in the object can be abbreviated (as will be mentioned later, as long as you know it can be used in this way at present),
ES6 allows you to write variables and functions directly in braces as object properties and methods. Such writing is more concise.
When the property name is the same as the value or method name, it can be abbreviated to one.

const { log: log } = console; // You can deconstruct existing objects
log('hello'); // hello
// The above code can be abbreviated as the following
const { log } = console;
log('hello') // hello

Use deconstruction assignment in nested objects.

// Multiple nesting, you can also nest arrays
let obj = {
  sample: [
    'Hello',
    { sample1: 'World' }
  ]
};

let { sample: [sample, { sample1 }] } = obj; 

console.log(sample,sample1); // Hello World

// Or like this? Add new content to an array or object
let obj = {};
let arr = [];

({ sample: obj.a, sample1: arr[0] } = { sample: 123, sample1: true });
console.log(obj); // {a: 123}
console.log(arr); // [true]

Default value

Similar to the default value of array deconstruction assignment, the default value of object

be careful:

  • When the attribute of an object is strictly equal to undefined, the default value will take effect.
  • The default value is not necessarily literal, and other variables assigned by deconstruction can also be referenced, but the variable must be declared.
// When the property value of the object does not exist, the default value takes effect
let {sample1 = 10, sample2 = 11} = {sample1:2};
console.log(sample1, sample2); // 2, 11 

//The default value takes effect only when the attribute value of the object = = = undefined
let { sample10 = 10, sample11 = 11, sample12 = 12 } = 
    { sample10: "", sample11: undefined, sample12: null };
console.log(sample10, sample11, sample12); // 11, , null

// The default value is variable
let {sample21 = 1, sample22 = sample21} = {};
console.log(sample21, sample22); // 1, 1

let sample30 = 31;
let {sample31 = sample30, sample32 = 3} = {};
console.log(sample31, sample32); // 31, 3

be careful

  1. If you want to use a declared variable for deconstruction assignment, you must be very careful.
  2. Deconstruction assignment allows no variable name to be placed in the pattern to the left of the equal sign.
  3. Because arrays are special objects in nature, they can be deconstructed.
// 1. Syntax error
let sample;
{sample:sample} = {sample: 1}; // Direct error reporting
/* 
    Because the JavaScript engine will interpret {sample} as a code block, resulting in syntax errors. This problem can only be solved by not writing curly braces at the beginning of the line and avoiding JavaScript interpreting them as code blocks.
*/

// 2. Meaningless but legal
({} = [true, false]);
({} = 'abc');
({} = []);

// 3. The array uses the deconstruction assignment of the object,
let { 0: sample0, 1: sample1 } = [1, 2];
console.log(sample0, sample1); // 1, 2

Deconstruction assignment of string

Strings can also be deconstructed and assigned.
When the string is deconstructed and assigned, the string is converted into an array of classes.
Class array also has the length attribute, so you can also get the length of the string in this way

let { length } = 'sample';
console.log(length); // 6

Deconstruction assignment of numeric and Boolean values

The rule of deconstruction assignment is to convert the value to the right of the equal sign into an object as long as it is not an object or array.
Since * * undefined * * and * * null * * cannot be converted into objects, an error will be reported when they are deconstructed and assigned.

// Deconstruction assignment of numeric and Boolean values
let { toLocaleString: sampleNum } = 111;
console.log(sampleNum === Number.prototype.toLocaleString);

let { toString: sampleBol } = true;
console.log(sampleBol === Boolean.prototype.toString);

// undefined and null for deconstruction assignment
let { prop: x } = undefined; // Direct error TypeError
let { prop: y } = null; // Direct error TypeError

Deconstruction assignment of function parameters

Deconstruction assignment is performed for function parameters. Function parameters need deconstruction assignment that can be deconstructed.

// When the parameter is an array, when the parameter is passed into the function, the array parameter is decomposed into variables sample1 and sample2.
function addNumberArr([sample1, sample2]) {
  return sample1 + sample2;
}

console.log(addNumberArr([4, 4])); // 8

// When the parameter is an object, the function deconstructs the parameter to obtain the values of the variables sample1 and sample2.
function addNumberObj({ sample1, sample2 }) {
  return sample1 + sample2;
}

console.log(addNumberObj({ sample1: 10, sample2: 20 })); // 30

Deconstruction of function parameters can also use default values.

// The function deconstructs this parameter to obtain the values of the variables sample1 and sample2.
// If the deconstruction fails, sample1 and sample2 are equal to the default values.

function sample({ sample1 = 0, sample2 = 0 } = {}) {
  console.log([sample1, sample2])
  return [sample1, sample2];
}

sample({ sample1: 1, sample2: 2 }); // [1, 2]
sample({ sample1: 1 }); // [1, 0]
sample({}); // [0, 0]
sample(); // [0, 0]

Parenthesis problem

What is the parenthesis problem?

It turns out that in the compiler, it is impossible to identify whether a formula is an expression or deconstruct the left part of the assignment equal sign before parsing to the equal sign, that is, the key (attribute) value on the left in pattern matching. So if you recognize parentheses, how should the compiler handle parentheses?

ES6 stipulates that parentheses shall not be used as long as there is ambiguity that may lead to deconstruction.
Ruan Yifeng suggested not to place parentheses in the pattern whenever possible.

Note: parentheses cannot be used in the following three cases

  1. Variable declaration statement
  2. Function parameters are also variable declarations, so they cannot be enclosed in parentheses.
  3. Mode of assignment statement

In the above three cases, parentheses are used to report errors directly.

// 1. Variable declaration statement
let [(sample)] =[1]; // Direct error reporting
let { sample: ({ sample1: sample1 }) } = { sample: { sample1: 2 } }; // Direct error reporting

// 2. Function parameters also belong to variable declaration, so they cannot be enclosed in parentheses.
function sampleFn([(sample)]) { return sample; } // Direct error reporting

// 3. Mode of assignment statement
({ sample2: sample21 }) = { sample2: 42 }; // Direct error reporting
[({ sample3: sample31 }), { sample4: sample41 }] = [{}, {}];

Parentheses can only be used in one case
There can be no declaration statement, and parentheses can be used for the non pattern (property name) part of the assignment statement.

({ sample: (sample) } = {}); // correct
console.log(sample); // undefined

Purpose of deconstruction assignment

Deconstruction assignment is mainly used on objects and arrays,

  1. Exchange values of variables

How do I exchange the values of two variables without using temporary variables? It can be implemented simply using deconstruction assignment.

// Deconstruction assignment of array
let sample1 = 2;
let sample2 = 4;
[sample1, sample2] = [sample2, sample1];
console.log(sample1, sample2); // 4 , 2
  1. Deconstruction assignment of multiple return values of function
// Object returned by deconstruction function
function sample() {
  return [1, 2, 3];
}
let [sample1, sample2, sample3] = sample();
console.log(sample1, sample2, sample3); // 1, 2, 3

// Object returned by deconstruction function
function sample() {
  return {
    sample11: 1,
    sample12: 2,
    sample13: 3,
  };
}
let {sample11, sample12, sample13} = sample();
console.log(sample11, sample12, sample13); // 1, 2, 3
  1. Extract JSON data

You can extract multiple data at once using deconstruction assignment

let sampleJson = {
  id: 11,
  status: false,
  data: [{ name: 'name1' }, { name: 'name2' }]
}
let { id, status, data } = sampleJson;
console.log(id, status, data);// 11, false, [{ name: 'name1' }, { name: 'name2' }]
  1. Specifying method of input module
const { SourceMapConsumer, SourceNode } = require("source-map"); // Sample code

Topics: ECMAScript