解构赋值

212 阅读2分钟

解构赋值:从数组和对象中提取值,对变量进行赋值,本质上,这种写法属于模式匹配

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] = {};

默认值

  1. 当一个数组成员 严格等于 undefined 时,默认值才会生效。
let [x = 1] = [undefined];
x  // 1

let [x = 1] = [null];
x  // null
  1. 如果默认值是表达式,那么这个表达式是惰性求值的。
function f() {
  console.log('aaa');
}

let [x = f()] = [1];  
x  // 1,因为 x 能取到值,所以函数 f 根本不会执行
  1. 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
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]

用途

  1. 交换变量的值
[x, y] = [y, x]