ES6-变量的解构赋值

ES6的解构赋值,可以让我们更加简洁、清晰的进行变量的声明与赋值,同时也减少了代码量,使得代码的可读性更强。

什么是解构赋值?

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

摘自阮一峰老师ECMAScript 6 入门

数组的解构赋值

ES5中为多个变量赋值:

1
var a = 1, b = 2, c = 3;

ES6中可以这样写:

1
2
3
4
let [a,b,c] = [1,2,3];
a;//1
b;//2
c;//3

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let [a,[[b],c]] =[1,[[2],3]];
a;//1
b;//2
c;//3

let [,,d] = [1,2,3];
d;//3

let [x, , y] = [1, 2, 3];
x; // 1
y; // 3

let [e, ...f] = [1, 2, 3, 4];
e; // 1
f; // [2, 3, 4]

let [x, y, ...z] = ['a'];
x; // "a"
y; // undefined
z; // []注意!

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

不完全解构

1
2
3
let [a,b,c] = [1,2,3,4];

let [x, [y], z] = [1, [2, 3], 4];

如果等号右边不是数组,或者严格地说,不是可遍历的结构,那么将会报错。

1
2
3
4
5
6
7
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

默认值

ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。

1
2
3
4
5
6
7
8
9
10
11
let [a = 'hello',b ='world'] = [];
a;//hello
b;//world

let [c='world',d='world'] = ['hello'];
c;//hello
d;//world

let [x='hello',y='world'] = [null];
x;//null
y;//world

利用结构赋值,可以简单的实现两个变量的值,[x,y]=[y,x]

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

对象的解构赋值

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let { name, age} = { name: 'test', age: 12};
name;//test
age;//12

let { grade, classes } = { classes: 2, grade: 3};
grade;//3
classes;//2

//嵌套
let person = {name: {firstName: "Green", lastName: "Tom"}};
let {name: {firstName, lastName}} = person;
firstName;//Green
lastName;//Tom

let person = {dateOfBirth: [1, 1, 1980]};
let {dateOfBirth: [day, month, year]} = person;
day;//1
month;//1
year;//1980

字符串的解构赋值

字符串在解构赋值时,被转换成了一个类数组的对象。类数组的对象的length属性,也可以进行解构赋值。

1
2
3
4
5
let [a,b,c,d,e]='hello';
a;//h

let {length: len} = 'hello';
len;//5

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。等号右边是undefined、null,由于不能转换成对象,会导致解构失败。

1
2
3
4
5
6
7
8
9
10
//数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。
let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

函数参数的解构赋值

1
2
3
4
5
6
7
8
function nameString([firstName ,lastName]){
return (lastName + ' ' + firstName);
}
nameString(['Green','Jim']);//"Jim Green"

//undefined会触发函数的默认值
[1, undefined, 3].map((x = 'yes') => x);
//[1,'yes', 3]