This is the 27th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Hello everyone, I am a bowl week, a front end that does not want to be drunk (inrolled). If I am lucky enough to write an article that you like, I am very lucky

Decoupled assignment of an array

What is array decoupling assignment

ECMAScript 2015 allows variables to be assigned by extracting values from arrays and objects in a pattern known as decoupled assignment.

Before ECMAScript 2015, variables are assigned as follows:

let a = 1;
let b = 2;
let c = 3;
Copy the code

ECMAScript 2015 allows the following.

let [a, b, c] = [1.2.3];
Copy the code

The decoupled assignment of ECMAScript 2015 is essentially pattern matching. The assignment operator has the same pattern on both sides, and the variable on the left is assigned the value of its position.

Array decoupling assignment failed

If the decoupling assignment fails, the value of the variable is undefined. The sample code looks like this:

// If there is no corresponding index in the array to the right of the = operator, the decoupled assignment fails and its value is undefined
let [v] = []
let [a, b] = [1]
console.log(v, a, b); // undefined 1, undefined
Copy the code

If you want to solve the problem of decoupling assignment failure, you need to keep the number of left and right sides of the assignment operator the same.

Incomplete decoupled assignment

Incomplete decoupled assignment means that the number of variables in the right-hand array of the assignment operator is greater than the number in the left-hand array, causing some variables in the right-hand array to fail, but in this case the decoupled assignment will still succeed.

The sample code looks like this:

// The number of variables on the left-hand side of the assignment operator is less than the number of values on the right-hand side
let [a, b, c] = [1.2.3.4]  // Still decouples assignment success
console.log(a, b, c); / / 1 2 3
Copy the code

The default value

Decoupled assignment allows you to specify default values. The sample code looks like this:

* let [var1 = value1, var2 = value2,...]  = [val1, val2,...] Var1,var2 stands for the variable name value1,value2 stands for the default value val1, val2 stands for the specified value */
let [a = 1, b = 2] = [100]
console.log(a, b); 2 / / 100
Copy the code

One thing to note when using the default values is that ECMAScript6 internally uses the full equals === operator to determine if all values at a given location are equal to undefined. The default values are valid only when all values are undefined. The test code is shown below:

let [a = 1, b = 2] = [100.undefined]
console.log(a, b); 2 / / 100
Copy the code

When we use null, even though null is also null, null! = = is undefined. So our default values will not take effect. The test code is as follows

let [a = 1, b = 2] = [100.null]
console.log(a, b); // 100 null
Copy the code

Complex case of array decoupling assignment

Since JavaScript is a weakly typed language, any type to the right of an assignment is allowed, which leads to the following special cases:

Case 1: To the right of the operator is a function with the following example code

// 1. The right-hand side of the operator is a function
let [a, b] = [1.function () {
  return 10;
}]
console.log(b()); / / 10
Copy the code

Case 2: An object is to the right of the operator

// 2. The right side of the operator is an object
let [a, b] = [1, {
  name: 'Fuchsbau Little Matchmaker'
}]
console.log(b); // { name: '狐妖小红娘' }
Copy the code

Case 3: An array of functions to the right of the operator

// 3. The right side of the operator is the contain array
let [a, b] = [1[2.3]]
console.log(b); // [2, 3]
Copy the code

Case 4: The left and right sides of the operator contain arrays, as shown in the following example code

// 4. The left and right sides of the operator contain arrays, as shown below
let [a, [b, c]] = [1[2.3]]
console.log(b); / / 2
Copy the code

Object decoupling assignment

The decoupled assignment of an object is implemented by one-to-one correspondence between the variable name and the attribute name of the object. The sample code looks like this:

/* * Decouple assignment of objects - Extract values from objects and assign values to variables! The variable name must correspond to the property name of the object, otherwise it will fail. * /
let {
  x,
  y
} = {
  x: 10.y: 20
}
console.log(x, y); / / 10 20
Copy the code

It is worth noting that the format of the assignment operator needs to be consistent on both sides.

A special case of object decoupling assignment

Since JavaScript is a weakly typed language, any type to the right of an assignment is allowed, which leads to the following special cases:

Case 1: To the right of the operator is a function with the following example code

// 1. The right-hand side of the operator is a function
let { a, b } = {
  a: 1.b: function () {
    return 10; }}console.log(b());/ / 10
Copy the code

Case 2: An object is to the right of the operator

// 2. The right side of the operator is an object
let {a, b} = {
  a: 1.b: {
    name: 'ywanzhou'}}console.log(b); // { name: 'ywanzhou' }
Copy the code

Case 3: An array of functions to the right of the operator

// 3. The right side of the operator is the contain array
let {a, b} = {
  a: 1.b: [1.2]}console.log(b); //[ 1, 2 ]
Copy the code

Case 4: There are objects on the left and right of the operator, as shown in the sample code below

// 4. The left and right sides of the operator contain objects
let {
  m: {
    name,
    age
  },
  n
} = {
  m: {
    name: 'test'.age: 20
  },
  n: 20
}
console.log(name, age); // test 20
Copy the code

Decoupling assignment failed

If the decoupling assignment fails, the value of the variable is undefined. The sample code looks like this:

// Failed to decouple assignment
let {
  a,
  b
} = {
  a: 10
}
console.log(b);
Copy the code

Incomplete decoupled assignment

Incomplete decoupled assignment means that the number of attributes on the right-hand side of the assignment operator is greater than the number of attributes on the left-hand side, causing some of the variables of the attributes on the right-hand side to fail, but in this case the decoupled assignment will still succeed.

// Incomplete decoupled assignment
let {
  a
} = {
  a: 10.b: 20
}
console.log(a);
Copy the code

The default value

Decoupled assignment allows you to specify default values. The sample code looks like this:

/ / the default value
let {
  a,
  b = 100
} = {
  a: 10.b: 20
}
console.log(b);
Copy the code

Decoupled assignment of string, numeric, and Boolean values

String decoupled assignment

Strings can also deconstruct assignments. This is because at this point, the string is converted to an array-like object.

let [h1, y, x] = "Bowl week."
console.log(h1, y, x, h2); / / a bowl of weeks
Copy the code

Decoupled assignment of numeric and Boolean values

If a direct decoupled assignment to a numeric/Boolean value throws an exception, the assignment operator to the right of a numeric/Boolean value is converted to an object first.

// let [a] = 100; TypeError: 100 is not iterable
// console.log(a);
// To decouple a Boolean or numeric value, change it to the object type now.
let {
  toString: b
} = 1;
console.log(b === Number.prototype.toString); // true

let {
  toString: c
} = true;
console.log(c === Boolean.prototype.toString); // true
Copy the code

The rule for deconstructing assignment is to turn the value to the right of the equals sign into an object whenever it is not an object or array. Undefined and NULL cannot be converted to objects, so destructuring assignments to them will result in an error.

Decoupled assignment of a function

Function arguments can also be destructively assigned. The sample code looks like this:

// Use arrays
function f([a, b]) {
  console.log(a, b);  
}
f([10.20]) / / 10 20
// Use objects
function fn({ a, b }) {
  console.log(a, b);
}
fn({
  a: 10.b: 20
})  / / 10 20
Copy the code

The little bracket problem

While decoupled assignments are convenient, they are not easy to parse. There is no way for the compiler to know from the start whether an expression is a pattern or an expression. It must be parsed to (or not) the equals sign.

This raises the question of what to do if there are parentheses in the schema. ECMAScript 2015 rules prohibit the use of parentheses where they could lead to ambiguity in deconstruction.

However, this rule is actually not so easy to discern and can be quite troublesome to deal with. Therefore, it is recommended that you do not place parentheses in schemas whenever possible.

The case where the parentheses cannot be used

There are three situations in which you cannot use curly braces

Case 1: Variable declaration statement, sample code shown below

// All of the following errors will be reported
let [(a)] = [1];

let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};

let { o: ({ p: p }) } = { o: { p: 2}};Copy the code

All six of the above statements report errors because they are variable declarations and the schema cannot use curly braces.

Case two: as a function parameter

Function arguments are also variable declarations and therefore cannot have parentheses.

/ / an error
function f([(z)]) { return z; }
/ / an error
function f([z,(x)]) { return x; }
Copy the code

Case 3: Pattern of assignment statements

// All errors are reported
({ p: a }) = { p: 42 };
([a]) = [5];
Copy the code

The code above puts the entire schema in parentheses, causing an error.

/ / an error
[({ p: a }), { x: c }] = [{}, {}];
Copy the code

The code above puts part of the schema in parentheses, causing an error.

Case where you can use curly braces

There is only one case where you can use curly braces: you can use curly braces on the non-schema part of an assignment statement.

[(b)] = [3]; / / right
({ p: (d) } = {}); / / right
[(parseInt.prop)] = [3]; / / right
Copy the code

All three of the above lines execute correctly because they are assignment statements, not declarations; Second, their parentheses are not part of the schema. In the first line, the schema takes the first member of the array, regardless of the parentheses; In the second line, the mode is P, not D; The third line of statements has the same properties as the first.

The usefulness of variable decoupling assignment

Variable decoupling assignment can be used in many ways, but here are a few common examples.

1. Swap variable values

If the exchange variable is not decoupled and requires a third variable, the sample code looks like this:

var a = 10,
  b = 20;

var c = a;
a = b
b = c
c = null  /// release variables
console.log(a, b); / / 20 10
Copy the code

With variable decoupling assignment, the sample code looks like this:

let a = 10,
  b = 20;
[a, b] = [b, a]
console.log(a, b); / / 20 10
Copy the code

Using this method is not only concise, but also easy to read, semantic clear.

2. Return multiple values from a function

A function can return only one value. If you want to return multiple values, you must return them in arrays or objects. With deconstructing assignments, it’s very convenient to pull out these values. The sample code looks like this:

// Return an array

function example() {
  return [1.2.3];
}
let [a, b, c] = example();

// Return an object

function example() {
  return {
    foo: 1.bar: 2
  };
}
let { foo, bar } = example();
Copy the code

3. Definition of function parameters

Destructuring assignments makes it easy to map a set of parameters to variable names.

// Arguments are an ordered set of values
function f([x, y, z]) {
  console.log(x, y, z);
}
f([1.2.3]);  / / 1 2 3

// Arguments are an unordered set of values
function fn({x, y, z}) {
  console.log(x, y, z);
}
fn({
  z: 3.y: 2.x: 1
});  / / 1 2 3
Copy the code

4. Extract JSON data

Destructuring assignments is especially useful for extracting data from JSON objects.

// Extract JSON data
let jsonData = {
  id: 42.status: "OK".data: [867.5309]};let {
  id,
  status,
  data: number
} = jsonData;

console.log(id, status, number); // 42, "OK", [867, 5309]
Copy the code

Phase to recommend

  • Summary of 42 front-end layout schemes – Juejin (juejin. Cn)
  • JS advanced must be 5 high order functions – nuggets (juejin. Cn)
  • 6 types of inheritance before ES6 – Digging gold (juejin.cn)
  • – Juejin (juejin. Cn)