Deconstruction assignment of arrays
ES6 allows you to extract values from arrays and objects according to a certain pattern and assign variables, which is called Destructuring.
This is called "pattern matching". As long as the patterns on both sides of the equal sign are the same, the variables on the left are assigned corresponding values.
es5 Writing method
let a = 1;
let b = 2;
let c = 3;
es6 Writing method
let [a, b, c] = [1, 2, 3]
let [foo, [[bar], baz]] = [1, [[2], 3]]
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"]
third // "baz"
let [x, , y] = [1, 2, 3]
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4]
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a']
x // "a"
y // If undefined // deconstruction is unsuccessful, the value of the variable is equal to undefined.
z // []
Incomplete Deconstruction: The pattern on the left of the equal sign matches only a portion of the array on the right of the equal sign.
let [x, y] = [1, 2, 3];
x
y
let [a, [b], d] = [1, [2, 3], 4];
a
b
d
The main premise of deconstruction is that the Iterator interface must be required.
Default: Deconstruction assignment allows default values to be specified
let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
//ES6 Internal use of strict equality operators(===),Determine whether a location is valuable. So, if an array member is not strictly equal toundefined,Default values are not valid
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
Object deconstruction assignment
There is an important difference between object deconstruction and array. The elements of an array are arranged in order, and the value of a variable is determined by its position; while the attributes of an object are not in order, the variables must have the same name as the attributes in order to get the correct value.
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo
bar
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo
bar
let { baz } = { foo: "aaa", bar: "bbb" };
baz
The variable name is not consistent with the attribute name and must be written as follows
var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f
l
let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz
foo
In this way, variable declaration and assignment are integrated. For let and const, variables cannot be redeclared, so once the assigned variable has been declared before, it will report an error.
let foo;
let {foo} = {foo: 1};
let baz;
let {bar: baz} = {bar: 1};
let foo;
({foo} = {foo: 1});
let baz;
({bar: baz} = {bar: 1});
Object deconstruction can also specify default values. The attribute value of an object is strictly equal to undefined
var {x = 3} = {};
x
var {x, y = 5} = {x: 1};
x
y
var {x:y = 3} = {};
y
var {x:y = 3} = {x: 5};
y
var { message: msg = 'Something went wrong' } = {};
msg
You can assign values to existing objects
let { log, sin, cos } = Math;
Arrays are special objects in nature, so they can be deconstructed as object attributes.
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first
last
String deconstruction assignment
Strings can also deconstruct assignments. This is because at this point, the string is converted into an array-like object.
const [a, b, c, d, e] = 'hello';
a
b
c
d
e
Objects like arrays have a length attribute, so you can also deconstruct and assign values to this attribute.
let {length : len} = 'hello';
len
Deconstruction Assignment of Numbers and Boolean Values
When deconstructing assignments, if the right-hand side of the equals sign is a number and a Boolean value, it will first be converted to an object.
let {toString: s} = 123;
s === Number.prototype.toString
let {toString: s} = true;
s === Boolean.prototype.toString
As long as the value on the right side of the equals sign is not an object or an array, it is converted to an object first. Because undefined and null cannot be converted to objects, deconstruction assignment of them will cause errors.
let { prop: x } = undefined;
let { prop: y } = null;
Deconstruction and Assignment of Function Parameters
Function parameters can also be assigned using deconstruction
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
Default values can also be used to deconstruct function parameters
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8});
move({x: 3});
move({});
move();
//Different ways of writing lead to different results
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8});
move({x: 3});
move({});
move();
Parentheses
Destruction assignment is convenient, but it is not easy to parse. For a compiler, it is impossible to know whether a formula is a pattern or an expression from the very beginning, but it must be resolved to (or not to) an equal sign.
The problem is what to do if parentheses appear in the schema. The rule of ES6 is that parentheses should not be used whenever it is possible to cause ambiguity in deconstruction.
However, this rule is actually not so easy to distinguish, and it is rather troublesome to deal with. Therefore, it is recommended that no parentheses be placed in the schema whenever possible.
In variable declaration statements, you cannot have parentheses.
let [(a)] = [1];
let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };
In function parameters, the mode can not be parenthesized, and function parameters belong to variable declaration.
function f([(z)]) { return z; }
In assignment statements, the whole pattern, or one layer of nested patterns, cannot be placed in parentheses.
// Full error reporting
({ p: a }) = { p: 42 };
([a]) = [5];
[({ p: a }), { x: c }] = [{}, {}];
[(b)] = [3];
({ p: (d) } = {});
[(parseInt.prop)] = [3];
purpose
(1) Values of exchange variables
let x = 1;
let y = 2;
[x, y] = [y, x];
(2) Return multiple values from a function: a function can only return one value, and if it wants to return multiple values, it can only return them in an array or an object. With deconstruction assignment, it is very convenient to extract these values.
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
(3) Definition of function parameters: Deconstruction assignment can easily correspond a set of parameters with variable names.
// A parameter is a set of ordered values
function f([x, y, z]) { ... }
f([1, 2, 3]);
// A parameter is an unordered set of values
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
(4) Extracting JSON data: Deconstruction assignment is especially useful for extracting data from JSON objects
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
(5) Default values of function parameters
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
}) {
// ... do stuff
};
//By specifying the default value of the parameter, you avoid rewriting var foo = config.foo inside the function body|| 'default foo';Such statements
(6) Traversing the Map structure: Any object deployed with the Iterator interface can be traversed in a for...of loop. Map structure supports Iterator interface naturally, and it is very convenient to obtain key names and key values with deconstruction assignment of variables.
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}