[toc]
### 解构的相关概念
#### 什么是解构
ES6中制定了一种语法规则,可以将一个对象或数组的某个属性提取到指定的变量中。
#### 解构的分类
ES6中解构可以分为对象解构和数组解构两种。
#### 解构的作用
解构可以很方便的从对象或数组中提取对应属性的值,减少代码量的书写。
### 对象解构
**对象的解构不会对被解构的对象产生任何影响,仅是从被解构的对象中获取数据。**
#### 对象解构的标准写法
```js
const student = {
classNum: 3,
name: "John",
age: 16,
address: {
province: '黑龙江',
city: '哈尔滨'
}
}
//上面定义了一个学生信息的对象,传统写法中若想要提取出对象的每一个属性会使用下面的方法
let classNum = student.classNum;
let name = student.name;
let age = student.age;
let address = student.address
//这样的写法在对象属性多的时候会增加代码量
//ES6中使用解构的方式来达到上方同样的效果,写法如下:
let {classNum, name, age, address} = student;
//上面的代码表示:先定义4个变量,然后从对象中读取同名属性,并将其value赋值给变量。
```
#### 解构中使用默认值
在对象解构的过程中(尤其是在ajax请求返回的对象中),很多时候我们并不确定对象中是否存在我们想要的属性。此时我们想实现一个效果:当对象中存在这个属性,就获取其属性值。当对象中不存在这个属性,就给需要取值的变量一个默认值。在解构中可以这样写:
```js
const student = {
classNum: 3,
name: "John",
age: 16,
address: {
province: '黑龙江',
city: '哈尔滨'
}
}
let {classNum, name, age, address, abc} = student;
//上面的代码中,student对象中并没有abc的属性。但在解构过程中abc的这个变量已被创建,所以其值为undefined。
let {classNum, name, age, address, abc = 123} = student;
//为了防止对象中不存在abc的属性,我们给abc属性一个默认值123,当student对象中存在abc属性,则abc使用student对象中同名属性的值,如果student对象中不存在abc这个属性,则abc的值为123。
```
#### 非同名属性的解构
如果在解构的过程中,定义的变量名与对象中的属性名不相同时,使用如下方法解构:
```js
//变量名与对象属性名不同时,使用{属性名:变量名}的方式。
const student = {
classNum: 3,
name: "John",
age: 16,
address: {
province: '黑龙江',
city: '哈尔滨'
}
}
//如果想用classNumber变量获取对象中classNum属性,可在属性名后面加冒号和变量名
//若想同时使用默认值,可以直接在新的变量名后面加默认值即可。
let {classNum: classNumber = 3, name, age, address, abc} = student;
```
#### 对象的深层解构
对于上面的student对象,如果我们只想获取name和city两个属性,可以使用下面的方法:
```js
let {name, address: {city}} = student;
//这条语句表示从address中进一步解构,获取city的值,并赋值给变量city
//若city中还存在更深层的对象,可以再嵌套进行解构。
//非同名或默认值的方法同上
```
### 数组解构
#### 数组解构的标准写法
在对象解构中获取数据的变量使{ }来包裹,数组解构中使用[ ]来包裹变量,例如:
```js
const arr = [1,2,3,4,5,6];
//如果想获取数组中前三位的值,写法如下
let [n1, n2, n3] = arr;
//此时n1=1,n2=2,n3=3
```
>数组解构中默认值的用法与对象相同。
>数组的解构是按照变量的排列顺序对应在数组中的排列顺序进行赋值的,所以如果需要不重名的变量,直接在解构变量的对应位置上修改变量名就可以
>如果只想获取数组中第1位和第3位的数据,只需把不需要获取数据的那位空出来就可以
```js
let [n1,,n3] = arr; //n1=1,n3=3
```
>同样,如果变量组的变量个数超出了数组的长度,多的变量可以赋默认值,或默认为undefined
#### 数组的深层解构
若数组中还嵌套着数组,需要获取深层数组中某个下标的值,例如:
```js
const arr1 = [1, 2, 3, [11, 22, 33], 5, 6, 9];
//若要获取数组中第4位的数组中第3位的数据,只需把前面的下标空位,并嵌套数组解构即可
let [,,,[,,n]] = arr1; //n的值为33
```
若数组中嵌套对象,可以使用数组解构嵌套对象解构的方式
```js
const arr3 = [1, 2, 3, {a: 11, b: 22, c: 66}, 5, 6, 9];
let [,,,{c: res}] = arr3; //res的值为66
```
>默认值和非同名属性解构等规则也同样适用
### 剩余项解构
无论是对象解构还是数组解构,如果我们需要获取第一位上的值给一个变量,其它除第一项以外的剩余部份赋值给一个新的数组。可以使用展开运算符。
```js
//针对对象的剩余解构
const student = {
class: 3,
name: "John",
age: 16,
address: {
province: '黑龙江',
city: '哈尔滨'
}
}
let {name, ...other} = student;
//name值为John,other对像中包含student对象中除name以外剩余所有属性。
//针对数组的剩余解构
const num = [1, 2, 3, [11, 22, 33], 5, 6, 9];
let [, n1, ...nums] =num;
//n1值为2,nums中包含从数组第3位开始到最后的所有数据(即:nums中并不包含数组下标第一位的1)。
```
**两者区别:对象剩余解构会获取除单独解构以外的所有属性值。数组解构仅会获取最后一个单独解构的位置之后的所有剩余属性,之前的数组下标的值,即使没有被其它变量获取,也不会被放在剩余解构的变量中**
### 解构的其它用途
#### 实现两个变量值的交换
```js
let a = 11, b = 22;
[b, a] = [a, b]; //通过数组解构的方式进行变量交换
console.log(a, b); //a的值22,b的值11
```
#### 参数解构(重点撑握)
当我们的函数的参数是一个对象,且函数体中需要用到参数对象的各个值,可以直接在参数位置进行解构。
```js
function print({class, name, age, address:{province, city}}){
console.log('班级', class);
console.log('姓名', name);
console.log('年龄', age);
console.log('所属省份', province);
console.log('所在城市', city);
}
print(student);
//在参数中解构就可以在函数体中直接使用对象中的属性。例如城市名就无需在函数体中写student.address.city了。
```
>参数解构会存在一个问题,当用户调用时没有给参数。那么系统默认参数为undefined或null,但是这两个对象是无法被解构的,即使在解构中设置了默认值也一样会报错。为了解决这个问题,可以结合参数默认值的方法。例如
```js
function ajax({method= 'get', url= '/app'} = {}){
//函数体
}
//我们把解构对象看做一个参数,如果没有值,默认值参数是一个空对象。这样就可以使用解构对象中的默认值。
ajax();
//method值为'get',url值为'/app'
```