首先我们来看一看解构的概念,在ES6标准下,允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称作解构,简而言之粗糙的理解就是变相赋值。
解构赋值的规则是,只要等号右边的值不是对象或者数组,就先将其转为对象。
一、数组的结构赋值
以前为变量赋值只能直接指定。而ES6允许从数组中提取值,按照对应位置对变量赋值,我们先来看下面一段代码
1 //ES5对变量赋值只能直接指定 2 var a = 10; 3 var b = 20; 4 var c = 30; 5 //ES6允许写成下面这样 6 let [a, b, c] = [10, 20, 40] 7 //a: 10 8 //b: 20 9 //c: 30 10 //本质上,这种写法属于“模式匹配”
在上面的代码段中提到了模式匹配,所谓模式匹配就是只要等号两边模式相同,左边的变量就会被赋予对应的值,看下面代码
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3
如果解构不成功,变量的值就等于underfined。解构赋值允许指定默认值,但是默认值生效的条件是一个数组成员严格等于(===)underfined,默认值才会生效,let [x = 1] = [underfined],此时x = 1生效。
二、对象的解构赋值
对象的解构赋值与数组有一个重要的不同,数组的元素是按照次序排列的,变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性值同名才能取到正确的值。我们先来看一段对象赋值的代码
let { bar, foo } = { foo: "aaa", bar: "bbb" } foo // "aaa" bar // "bbb" let { baz } = { foo: "aaa", bar: "bbb" } baz // underfined
从上面的代码中可以看出,等号左边的两个变量的次序和等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致去不导致,最后等于underfined。如果变量名与属性名不一致,必须写成下面这样:
let { foo: baz } = { foo: "aaa", bar: "bbb" };这样baz就能取到值,这种也是模式匹配,foo是模式,baz才是变量。对象解构中模式匹配常用于嵌套对象模式匹配。
三、字符串解构赋值
字符串也可以解构赋值,这是因为此时字符串被转换成了一个类似数组的对象。看下面一段代码
const [a, b, c, d, e] = 'hello' a // h b // e c // l d // l e // o
数值和布尔值姐解构赋值业火先将数值和布尔值转为对象在进行解构赋值。
四、用途
1、交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
此时x和y的值已经发生了替换,换做以前,只能通过中间变量来实现。
2、从函数返回多个值
function example () {
return [1, 2, 3]
}
let [a, b, c] = example ();此时a=1,b=2,c=3
3、函数参数的定义
function f ([x, y, z]) { ... }
f([1, 2, 3])
4、提取JSON数据
1 let jsonData = { 2 id: 42, 3 status: "OK", 4 data: [867, 5309] 5 }; 6 7 let { id, status, data: number } = jsonData; 8 9 console.log(id, status, number); 10 // 42, "OK", [867, 5309]