认识解构
按照一定模式从数组和对象中提取值,然后对变量进行赋值,成为解构
数组的解构
当我们需要同时给多个变量赋值时,传统的赋值方法如下:
var a=1;
var b=2;
var c=3;
在ES6中,我们还可以这样写:
var [a,b,c]=[1,2,3];
相比于之前的代码,这样写是不是更简便呢?这一段代码表示,可以从数组中提取值,按照位置赋给相应的变量。
如果等号左边的模式只匹配一部分的等号右边的数组,成为不完成解构
var [a,,b]=[1,2,3];
//a = 1
//b = 2
解构的嵌套结构
var [a,b,c]=[1,[2,3],4];
//a = 1
//b = [2,3]
//c = 4
我们可以通过 … 赋值给一个数组,写法如下:
var [a,...b]=[1,2,3,4,5];
//a = 1
//b = [2,3,4,5]
如果解构不成功变量的值就等于undefined,数组会等于空数组。
var [a,b,...c]=[1];
//a = 1
//b = undefined
//c = []
如果等号右边的不是数组,那么将会报错
var [a,b,...c]=1;
//报错: 1 is not iterable
解构赋值允许指定默认值
var [a,b=2]=[1]
//a = 1
//b = 2
如果数组成员不存在,或者等于undefined时都会使用默认值,但当数组成员为null时,默认值则不会生效
var [a,b=2,c=3]=[1,undefined,null]
//a = 1
//b = 2
//c = null
对象的解构
在认识解构中我们了解到,不止数组可以解构,对象依然可以。但是对象的解构和数组有所区别,数组的解构是通过对应位置而为变量赋值的,但在对象中其属性是没有位置之分的,所以对象的解构依赖是对象属性名,所赋值变量必须和属性名一致才可以拿到对应值。
var {name,age}={name:"aaa",age:32}
//name = "aaa"
//age = 32
交换变量位置得到的值一致
var {age,name}={name:"aaa",age:32}
//name = "aaa"
//age = 32
和数组解构相同,对象解构也存在不完全解构的情况
var {age}={name:"aaa",age:32}
//age = 32
如果变量名和属性名不一致,得到undefined
var {sex}={name:"aaa",age:32}
//sex = undefined
但是在实际编程中,如果已经存在和属性名一样的变量名,如果用同名变量将会覆盖前面的值时,就需要用到下面这种情况:
let name = "bbb";
let {name:newName,age}={name:"aaa",age:32}
//name = "bbb"
//newName = "aaa"
//age = 32
对象解构的嵌套:
var student={
name: "aaa",
grade: [
{
course: "A",
score: 80
},
{
course: "B",
score: 50
}
]
}
var {name,grade:[{course:course1,score:score1},{course:course2,score:score2}]} = student;
//name = "aaa"
//course1 "A"
//score1 = 80
//course2 = "B"
//score2 = 50
上诉代码进行了三层解构,先对name和garde两个属性结构,第二步,对grade数组结构,第三步,对数组的每一项的对象的course和score属性结构。
注意:如果打印grade会报错:grade is not defined,因为grade只是模式不是变量
对象的解构也可以指定默认值,具体方法和数组解构相同:
var {name,sex='男',age=0,tel,photo,adress} = {name: 'aaa', age: 23,photo: null,adress:undefined}
//name = 'aaa'
//sex = '男'
//age = 23
//tel = undefined
//photo = null
//adress = undefined
由于对象的界定符为{},而代码块的界定符也是{},所以当我们将一个已经声明的变量用于解构赋值时将会报错
var name;
{name} = {name:"aaa"}
如果将{}写在一行之首,JavaScript引擎会将其解释为一个代码块,所以为了解决这一问题,引入了(),上诉代码改造如下:
var name;
({name} = {name:"aaa"})
//name = "aaa"
用一个圆括号将我们的代码包裹起来,避免{}处于行首,也就避免了被JavaScript引擎解释为大括号的情况。
而数组解构不存在这一情况
var name;
[name] = ['aaa']
//name = 'aaa'
解构赋值允许等号左边的模式之中不放置任何变量名,这样可以写出十分古怪的表达式,它们可能毫无意义,但语法上是合法的,可以执行,如:
({}={name:"a"})
由于数组是特殊的对象,因此可以对数组进行对象的解构
var {0:a,1:b}=[1,2]
//a = 1
//b = 2
字符串的解构
字符串也可以解构赋值,此时字符串被转化成了类似数组的对象。
const [a,b,c]='123';
//a=1
//b=2
//c=3
let {length:len} = 'hello'
//len=5
参考书籍《ES6标准入门》