ES6
允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
1 数组的解构赋值
基本用法
以前,为变量赋值,只能直接指定值。
let a = 1;
let b = 2;
let c = 3;
现在,ES6
可以这样写:
let [a, b, c] = [1, 2, 3];
上面代码表示,可以从数组中提取值,按照对应位置,给变量赋值。
还支持嵌套数组。
let [x, [[y], z]] = [1, [[2], 3]];
x // 1
y // 2
z // 3
let [x, , y] = [1, 2, 3];
x // 1
y // 3
如果解析不成功,变量的值就等于undefined。
let [x] = []; // undefined
let [y, x] = [1]; // undefined
上面两种情况都属于解析不成功,x的值都会等于undefined。
还有一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。
let [x, y] = [1, 2, 3];
x // 1
y // 2
上面情况属于不完全解构,但依然可以成功。
默认值
解构赋值允许指定默认值。
let [ret = true] = [];
ret // true
let [x, y = 'b'] = ['a'];
x // 'a'
y // 'b'
2 对象的解构赋值
解构不仅用于数组,还可以用于对象。
let {x, y} = { x:10, y:20 };
x // 10
y // 20
与数组相比,对象解构有一个很重要的不同是,数组元素是按次序排列的,变量的取值由位置决定;而对象的属性没有次序,只要变量与属性同名,就能取到正确的值,否则为undefined
。
let { z, y, x } = { x:10, y:20 };
x // 10
y // 20
z // undefined
实际上,对象解构的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者。
let { pos1:x } = { pos1:10, pos2:20 };
x // 10
pos1 // error: pos1 is not defined
上面代码中,pos1是匹配的模式,x才是真正的变量。所以被赋值的是变量x,而不是模式pos1。
利用对象的解构赋值,可以很方便地将现有对象的属性,赋值到某个变量。
let node = { width:100, height:200, zIndex:5 };
let { zIndex:z, width:w, height:h, tag} = node;
z // 5
w // 100
h // 200
tag // undefined
3 字符串的解构赋值
字符串也可以被解构赋值,这是因为,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
类似数组的对象都有一个length属性,因此也可以对这个属性做解构赋值。
let [length:len] = 'hello';
len // 5
4 实际用途
4.1 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
上面代码交换x和y的值,这种写法简洁易读,语义非常清晰。
4.2 提取JSON数据
let jsonData = {
id: 5,
status: "OK",
data: [100, 200]
};
let { id, status, data:number } = jsonData;
console.log(id, status, number);
// 42, "OK", [100, 200]