解构赋值:从数组和对象中提取值,对变量进行赋值,本质上,这种写法属于模式匹配。
let [a, b, c] = [1, 2, 3];
let [foo, [[bar], baz]] = [1, [[2], 3]]; // foo = 1, bar = 2, baz = 3
let [head, ...tail] = [1,2,3,4]; // head:1, tail:[2,3,4]
解构不成功,变量值就为 undefined
let [foo] = [] // foo = undefined
let [x, y, ...z] = ['a']; // x = 'a', y = undefined, z = []
不完全解构,也可以解构成功
let [x, y] = [1, 2, 3];
如果等号右边不是数组或可遍历结构,那么会报错
事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
// 以下均会报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
默认值
- 当一个数组成员 严格等于 undefined 时,默认值才会生效。
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
- 如果默认值是表达式,那么这个表达式是惰性求值的。
function f() {
console.log('aaa');
}
let [x = f()] = [1];
x // 1,因为 x 能取到值,所以函数 f 根本不会执行
- 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
函数参数的解构
下面是指定 x 和 y 的默认值的解构赋值,
function move({x = 0, y = 0} = {}) { // 成员严格等于undefined,默认值生效
console.log([x, y]);
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
这个是为函数的参数整体指定默认值(当没有实参时才会使用默认值),而不是为变量 x 和 y 指定默认值。
function move({x, y} = {x: 0, y: 0}) {
console.log([x, y]);
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
用途
- 交换变量的值
[x, y] = [y, x]