This is a creation in Article, where the information may have evolved or changed.
ES6 allows values to be extracted from arrays and objects (as well as strings, values, Booleans, function parameters, and so on) in a certain pattern, which is called a deconstructed assignment, by assigning a value to the variable in the corresponding position. First, assuming that you already know what a deconstruction assignment is, let's take a quick look at its common uses.
1. Value of the interchange variable
let x = 1, y = 2;
[x, y] = [y, x];
Compared with the traditional way of introducing intermediate variables for value exchange, this writing is not only concise, but also easy to read, and the semantics are very clear
Multiple return values for parsing functions
Functions in JS can only return one value. If you want to return multiple values, you can only return them in an array or object. By destructuring and assigning values, we can easily take these values out and assign them to other variables.
// return an array
function arr () {
return [1,2,3];
}
let [x, y, z] = arr ();
// return an object
function obj () {
return {
foo: 1,
bar: 2
}
}
let {foo, bar} = obj ();
Define function multi-parameter input method
Destructuring assignment can easily correspond to a set of actual parameter names.
// parameter is an ordered set of values
function f ([x, y, z]) {...}
f ([1,2,3]);
// parameter is an unordered set of values
function f ((x, y, z)) {...}
f ((y: 2, x: 1, z: 3));
4. Extract JSON data
Destructuring assignment is especially useful for extracting data from JSON objects.
let jsonData = {
id: 20,
status: 'OK',
data: [12,34]
};
let (id, status, data: number) = jsonData;
console.log (id, status, number); // 20 'OK' [12,34]
5. When traversing the data structure of the Iterator interface, that is, when the for ... of loop traverses each item of itself, multiple parameters can be passed directly. The Map structure natively supports the Iterator interface. Using the destructuring assignment of variables, you can easily obtain the key names and values.
var map = new Map ();
map.set ('first', 'hello');
map.set ('second', 'world');
for (let item of map) {
console.log (item);
}
for (let [key, value] of map) {
console.log (key + 'is' + value);
}
for (let [i, j] of map) {
console.log (i + 'is' + j); // The result is the same as above
}
If you only want to get the key name, or only the key value, you can write it as follows
// Get the key name
for (let [key] of map) {...}
// Get key value
for (let [, value] of map) {...}
6. Get the specified method of the module
After loading the module, it is often necessary to specify variables again to get some methods of the module. Destructuring assignment directly streamlines this process.
const {SourceMap, SourceNode} = require ('source-map');
Let's introduce Destructuring assignment in detail.
Destructuring assignment of array
Previously, assigning values to variables could only specify values directly
let a = 1, b = 2, c = 3;
ES6 now allows this
let [a, b, c] = [1,2,3]
It looks similar to golang's multi-parameter assignment. The code here actually extracts the value from the array and assigns it to the variable according to the corresponding position. In essence, this writing is "pattern matching". As long as the pattern on both sides of the equal sign is the same, the variable on the left will be assigned a corresponding value.
let [foo, [[bar], bar]] = [1, [[2], 3]];
let [,, third] = ['foo', 'bar', 'baz']
let [x ,, y] = [1,2,3]
let [head, ... tail] = [1,2,3,4];
let [x, y, ... z] = ['a'];
If the destructuring is unsuccessful, the value of the variable will be equal to undefined. If the value to the right of the equal sign is not a traversable data structure (no Iterator interface), then an error will be reported
// Report error
let [foo] = 1;
let [foo] = undefined;
let [foo] = null;
let [foo] = false;
let [foo] = NaN;
let [foo] = {}; // Note that ordinary objects do not have an Iterator interface and cannot be traversed.
// for loop traversal, arrays and objects can be traversed using for ... in, where the parameter value passed in during array traversal is the index, the object is passed in attributes, and the array can also be traversed using the forEach method
For Set structures, you can also use array destructuring assignment
let [x, y, z] = new Set (['a', 'b', 'c']);
Important: In fact, as long as a data structure has an Iterator interface, destructuring assignments in the form of arrays can be used.
function * fibs () {
let a = 0, b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs ();
console.log (sixth); // 5
In the above code, fibs is a Generator function, which has an Iterator interface natively. Deconstructed assignments will obtain values from this interface in turn.
Destructuring assignment allows you to specify a default value. The default value takes effect only when the array member is strictly equal to undefined. If the default value is an expression, then the expression is lazily evaluated, that is, it is evaluated only when it is used.
function f () {...}
let [x = f ()] = [1];
In the above code, because x can get a value, the function f will not be executed at all.
2. Destructuring assignment of objects
Destructuring assignment can be used not only for arrays, but also for objects
let {foo, bar} = {foo: 'aaa', bar: 'bbb'}
The more common is when exporting module objects in Node:
let a = 1, b = 2;
// let obj = (a, b)
module.exports = (a, b)
There is an important difference between the destructuring of an object and an array. The elements of an array are arranged in order, and the value of a variable is determined by its position. The attribute of an object has no order. The variable must have the same name as the attribute to obtain the correct value.
let {foo, bar} = {bar: 'bbb', foo: 'aaa'}
let {baz} = {foo: 'aaa', bar: 'bbb'}
In the first line of the above statement, the order of the two variables on the left side of the equal sign is inconsistent with the order of the two attributes with the same name on the right side of the equal sign, but it has no effect on the value. Property name of the same name, so it cannot get a value, it is undefined
If the required variable name is clearly inconsistent with the property name, it must be written as follows:
let {foo: baz} = {foo: 'aaa'};
console.log (baz); // aaa
let {first: f, last: l} = {first: 'hello', last: 'world'}
console.log (f, l); // hello world
This actually shows that the destructuring assignment of an object is a shorthand of the form:
let {foo: foo, bar: bar} = {foo: 'aaa', bar: 'bbb'}
In other words, the internal mechanism of object destructuring and assignment is to find the attribute with the same name first, and then assign the value of the attribute to the variable that matches the pattern. The latter is actually assigned, not the former. The destructuring and assignment of objects can easily assign the methods of existing objects to a certain variable.
Since an array is a special object in nature, it is possible to deconstruct the object attributes of the array
let arr = [1,2,3];
let {0: first, [arr.length-1]: last} = arr; // Square brackets, this is a "property name expression"
console.log (first, last); // 1 3
3. Destructuring assignment of strings
Strings can also be deconstructed and assigned, because strings are first converted to an array-like object by default.
const [a, b, c, d, e] = 'hello';
console.log (a, b, c, d, e);
let {length: len} = 'hello';
console.log (len); // 5 array-like objects have a length property
4. Deconstructive assignment of numeric and Boolean values
When destructuring assignment, if the right side of the equal sign is a numeric value and a Boolean value, it will be converted to an object first.
let {toString: s} = 123;
console.log (s); // Number.prototype.toString
let {toString: s} = true;
console.log (s); // Boolean.prototype.toString
The rule for destructuring assignment is to convert an object to an array if the rule to the right of the equal sign is not an object or an array. If it cannot be converted to an object, such as null or undefined, an error will be reported.
5. Destructuring assignment of function parameters
Function arguments can also be assigned using destructuring
function add ([x, y]) {...}
add ([1,2]);
In the above code, the parameter of the function add is an array on the surface, but the moment the parameter is passed in, the array parameters are decomposed into the variables x and y. For the code inside the function, the parameter they can feel is x And y.
Here is another example:
[[1,2], [3,4]]. Map (([x, y]) => x + y); // [3,7]
Destructuring assignment of function parameters can also use default values
function move ({x = 0, y = 0} = {}) {
return [x, y]
}
move (); // [0,0]
move ({}); // [0,0]
move ({x: 2}); // [2,0]
move ({x: 2, y: 3}); // [2,3]
// The default value will be considered only when the value of the passed parameter is `undefined`. When reading, you can set aside the default value to make it easier to read.
In the above code, the parameter of the function move is an object, and the default value is set to {}. By destructing the passed object, the values of the variables x and y are obtained. If the destruction fails, x and y are equal to the default values.
Note that the writing below is slightly different
function move ((x, y) = (x: 0, y: 0}) {
return [x, y]
}
move (); // [0,0]
move ({}); // [undefined, undefined]
move ({x: 2}); // [2, undefined]
move ({x: 2, y: 3}); // [2,3]
The default value of this function parameter is {x: 0, y: 0}, which is different from the above.
6. Parentheses
Equal signs cannot be used in the pattern of variable declaration statements, function parameters, and assignment statements. There is only one case where parentheses can be used: the non-schema portion of an assignment statement.