ES6 变量解构赋值

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

一个最简单的例子

1
2
3
4
5
6
var [a,b,c] = [1,2,3];// a=1, b=2, c=3
// 这其实是一种模式匹配,只要两边的模式相同,就能正确地赋值:
let [a,[b,c]] = [1,[2,3]];// a=1, b=2, c=3
let [ , ,c] = [1,2,3];// c=3
let [c] = [1,2,3];// c = 1
let [a,c] = [1];// a = 1, c undefined

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

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

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

1
2
3
4
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
let {first,second} = {first:1,second:2};
let {third,fourth} = {fourth:4,third:3};
console.log(first,second,third,fourth);// 1,2,3,4

// 如果变量名与属性名不一致,则:
let {first:number} = {first:1};
console.log(number); // 1
console.log(first); // Uncaught ReferenceError

// 可以正确赋值
let number = {
first: 1,
second: 2
}
let {first,second} = number; //first = 1, second = 2

// 正确嵌套的可以赋值
var node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
var { loc: { start: { line }} } = node;
line // 1
loc // error: loc is undefined
start // error: start is undefined

对象的解构也可以指定默认值(默认值生效的条件是,对象的属性值严格等于 undefined ):

1
2
3
4
5
6
7
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var { message: msg = "biubiubiu" } = {};
msg // "biubiubiu"

三、字符串的解构赋值
字符串被转换成了一个类似数组的对象。

1
2
3
4
let [a,b,c] = 'abc';
console.log(a,b,c);// a=a,b=b,c=c
let {length:len} = 'byebye';
console.log(len);// 6

四、数值和布尔值的解构赋值
如果等号右边是数值和布尔值,则会先转为对象。

1
2
3
4
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true

五、函数参数的解构赋值(用得最多的地方)
函数 add 的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量 x 和 y 。对于函数内部的代码来说,它们能感受到的参数就是 x 和 y

1
2
3
4
5
6
7
8
9
10
11
12
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
// 函数参数的解构也可以使用默认值。
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]