数组解构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被成为解构;

以前,为变量赋值,只能直接指定值

let a = 1;
let b = 2;
let c = 3;

 

ES6 允许写成下面这样

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 // undefined
z // []

 

如果解构不成功,变量的值就等于 undefined

let [foo] = [];
let [bar, foo] = [1];

 

另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

 

如果等号的右边不是数组(或者严格地说,不是可遍历的解构,参见《Iterator》一章),那么将会报错。

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

 

事实上,只要某种解构具有Iterator接口,都可以采用数组形式的解构赋值。

 

function* fibs() {
let a =0 ;
let b =1;
while (true){
       yield a;
       [a, b] = [b, a + b];
   }
}


let [first, second, third, fourth, fifth, sixth] = fibs();
sixth  //5

 

上面代码中, fibs是一个Generator函数(参见《Generator函数》一章),原生具有Iterator接口,解构赋值会依次从这个接口获取值。

 

解构赋值允许指定默认值

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 内部使用严格相等运算符 (===),判断一个位置是否是有值。所以,只有当一个数组成员严格等于undefined, 默认值才会生效。

let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null

上面代码中,如果一个数组成员是 null , 默认值就不会生效, 因为null 不严格等于 undefined

如果一个默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

function f() {
  console.log('aaa');
}
let [x = f()] = [1];

等价于

let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}

 

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

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 做默认值时, y还没有声明。

 

posted on 2022-02-19 16:32  zhishiyv  阅读(41)  评论(0编辑  收藏  举报

导航