解构赋值 语法是一种 Javascript 表达式。可以将数组中的值或对象的属性取出,赋值给其他变量。
你可以使用解构赋值将对象字面量的属性绑定到变量。就像这样 let { bar } = foo。这会创建一个名为 bar 的变量,并且将 foo 对象中属性名与之相同的属性的值赋给它。
基本使用
解构赋值语句以声明关键字开始,赋值的左侧定义了要从原变量中取出哪些值。
解构可迭代对象:
const x = [1, 2, 3, 4, 5];
const [y, z] = x;
// 这创建了两个变量
// const y = x[0];
// const z = x[1];
任何可迭代对象(不一定是数组)都可以解构。
在从赋值语句右侧指定的长度为 N 的数组解构的数组中,如果赋值语句左侧指定的变量数量大于 N,则只有前 N 个变量被赋值。其余变量的值将是 undefined。
const foo = ["one", "two"];
const [red, yellow, green, blue] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // undefined
console.log(blue); //undefined
解构对象:
const obj = { a: 1, b: 2 };
const { a, b } = obj;
// 这创建了两个变量
// const a = obj.a;
// const b = obj.b;
解构对象时使用自定义名称:
const obj = { a: 1, b: 2 };
const { a, b: c } = obj;
// 这创建了两个变量
// const a = obj.a;
// const c = obj.b;
// 并没有创建 b
解构深层对象和数组:
const obj = { a: 1, b: { c: 2 } };
const {
a,
b: { c },
} = obj;
// 这创建了两个变量
// const a = obj.a;
// const c = obj.b.c;
绑定与赋值
对于对象和数组的解构,有两种解构模式:绑定模式 和 赋值模式,它们的区别是有无声明关键字。
绑定模式
在绑定模式中,模式以声明关键字(var、let 或 const)开始。然后,每个单独的属性必须绑定到一个变量或进一步解构。
const obj = { a: 1, b: { c: 2 } };
const {
a,
b: { c },
} = obj;
// Two variables are bound: `a` and `c`
所有变量共享相同的声明,因此,如果你希望某些变量可重新分配,而其他变量是只读的,则可能需要解构两次——一次使用 let,一次使用 const。
赋值模式
在赋值模式中,模式不以关键字开头。每个解构属性都被赋值给一个赋值目标——这个赋值目标可以事先用 var 或 let 声明,也可以是另一个对象的属性——一般来说,可以是任何可以出现在赋值表达式左侧的东西。
const numbers = [];
const obj = { a: 1, b: 2 };
({ a: numbers[0], b: numbers[1] } = obj);
// The properties `a` and `b` are assigned to properties of `numbers`
当使用对象字面量解构赋值而不带声明时,在赋值语句周围必须添加括号 (),否则行开头的 { 会被当作语句块解释而报错。
默认值
每个解构属性都可以有一个默认值。当属性不存在或值为 undefined 时,将使用默认值。如果属性的值为 null,则不使用默认值,而使用 null。
const [a = 1] = []; // a is 1
const { b = 2 } = { b: undefined }; // b is 2
const { c = 2 } = { c: null }; // c is null
赋值到新的变量名并提供默认值:
const { a: aa = 10, b: bb = 5 } = { a: 3 };
console.log(aa); // 3
console.log(bb); // 5
默认值可以是任何表达式。仅在必要时计算表达式的值。
const { b = console.log("hey") } = { b: 2 };
// Does not log anything, because `b` is defined and there's no need
// to evaluate the default value.
剩余属性
你可以使用剩余属性(...rest)结束解构模式。此模式会将对象或数组的所有剩余属性存储到新的对象或数组中。
const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(others); // { b: 2, c: 3 }
const [first, ...others2] = [1, 2, 3];
console.log(others2); // [2, 3]
剩余属性必须是模式中的最后一个,并且不能有尾随逗号。
数组解构赋值的剩余属性可以是另一个数组或对象绑定模式。这允许你同时提取数组的属性和索引。
const [a, b, ...{ pop, push }] = [1, 2];
console.log(a, b); // 1 2
console.log(pop, push); // [Function pop] [Function push]
const [a, b, ...[c, d]] = [1, 2, 3, 4];
console.log(a, b, c, d); // 1 2 3 4
这些绑定模式甚至可以嵌套,只要每个剩余属性都在列表的最后。
const [a, b, ...[c, d, ...[e, f]]] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c, d, e, f); // 1 2 3 4 5 6
另一方面,对象解构只能有一个标识符作为剩余属性。
const { a, ...{ b } } = { a: 1, b: 2 };
// SyntaxError: `...` must be followed by an identifier in declaration contexts
let a, b;
({ a, ...{ b } } = { a: 1, b: 2 });
// SyntaxError: `...` must be followed by an assignable reference in assignment contexts
类似语法
以下语法类似:
- 解构赋值;
for...in和for...of循环中的循环变量;- 函数参数;
catch绑定变量。
参考
解构赋值
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment