解构赋值的意思是指:按照一定的模式从数组和对象中提取值,将提取的值对变量进行赋值。
数组的解构模式:
1:按照等号两侧的数组对应的位置进行取值赋值,
1.1:如果等号两侧的数组结构和嵌套结构相同,则可以成功解构
1.2:如果等号两个的数组解构或嵌套解构不同,则解构不成功,解构不成功则对应位置的变量就赋值为undefined,数组(左).length > 数组(右).length
1.3:如果等号左侧的模式只匹配到一部分的等号右侧的数组,则可以成功解构,数组(左).length < 数组(右).length
1.4:如果右侧不是数组,将会报错
1.5:set等具有Iterator接口的结构都可以进行解构
2:解构的同时可以赋值默认值
let [foo = true] = []//foo = true
默认值生效规则:
2.1:使用严格相等运算符(===),判断一个位置是否有值,只有当等号右侧数组的一个成员严格等于undefined,默认值才会生效。如果一个数组成员是null,默认值不会生效,因为null 不严格等于undefined。
let [foo = 1] = [null]//foo = null
2.2:如果默认值是一个表达式,那么这个表达式是惰性求值,即只有在用到的时候,才会求值
function f(){
console.log('111')
}
let [x=f()] = [1]//x = 1
let [x=f()]=[]//x=f()
2.3:默认值可以引用解构赋值的其他变量,但该变量必须已经声明,否则会报错
let [x=1,y=x] = [];//x=1,y=2
let [x=y,y=1] = [];//ReferenceError:y is not defined
对象的解构赋值
1.1:对象的解构模式不同于数组,数组按照元素次序,对象没有次序,但变量必须与对象属性同名,才能取到正确的值
1.2:当代码中使用的变量名和对象解构的属性名不同时,可以进行转义:
let {foo:baz} = {foo:'aaa',bar:'bbb'};//baz = 'aaa';baz是自己定义的变量名,foo是对象的属性名,此处是匹配的模式,这样就可以在代码中还使用变量baz获取对象中foo中的值,真正赋值的是变量baz,而模式foo并没有被赋值
1.3:同数组一样,解构也可以用于嵌套结构的对象;
对象嵌套结构的解构需要注意:
let obj = {
p:[
'Hello',
{y:'World'}
]
};
let {p:[x,{y}]} = obj//此时p是模式,不会真正被赋值,被赋值的只有x,y
let {p,p:[x,{y}]} = obj//这种才能解构出p
1.4:解构赋值时子对象所在的父属性不存在,将会报错,相当于对undefined取.xxx,当然会报错
1.5:对象解构赋值可以取到继承的属性
2:解构时赋值默认值
2.1:默认值生效的条件时对象属性严格等于undefined
2.2:已经声明的变量再进行解构会报错;js引擎会将{}理解为代码块,从而发生语法错误,只有不将大括号写在行首,避免js将其解释为代码块,才能解决问题。
let x;
({x} = {x:1})
2.3:数组也可以解构成对象属性
let arr = [1,2,3]
let {0:first,[arr.length-1]:last} = arr//此时first,last分别被赋值到arr中的1,3
3:字符串的解构赋值
字符串被转换成一个类似数组的对象。
3.1:解构字符串内容
let [a,b,c,d,e] = 'Hello'//a='H',b='e',c='l',d='l',e='o'
3.2:解构字符串长度
let {length :len} = 'hello'//len=5
4:数值和布尔值的解构赋值
将数值和布尔值先转为对象
模式:只要等号右侧的值不是对象或数组,就先将其转换为对象,由于undefined和null无法转为对象,所以对它们进行解构赋值都会报错。
5:函数的参数进行解构赋值
*参数赋值分给‘函数参数’赋默认值 和 给给‘解构参数’赋默认值
5.1:给解构参数赋默认值:
function move({x=0,y=0}={}){//函数的参数是一个对象,对象解构的参数x,y,给解构的参数x,y赋值默认值0
return [x,y]
}
给函数参数赋值默认值
function move({x,y} = {x:0,y:0}){//赋值一个默认的参数:{x:0,y:0}当函数入参为空时,即为undefined时,才会将默认参数解构赋值给x,y
return [x,y]
}
6:解构赋值的用途:
合理使用解构赋值可以使代码简洁清晰
6.1:交换变量的值
let x=1;
let y=2;
[x,y]=[y,x]//x=2,y=1
6.2:从函数返回多个值
原本函数只能返回一个值
现在函数可以返回一个数组或是对象,然后通过解构赋值取出更多的值来
6.3:函数参数的定义
可以通过解构,直接定义函数体中使用的参数
6.4:提取JSON数据
解构赋值对提取JSON对象中的数据,尤其有用
6.5:函数参数的默认值***
给函数参数赋值默认值,可以减少写保底参数
let foo = config.foo || 'xxx'//不用再像这样写保底参数
function test(foo='xxx'){
conosle.log(foo)
}
test('kkk')//'kkk'
test()//'xxx',输出保底'xxx'
6.6:遍历Map结构
使用for...of循环遍历,通过解构获取键名和键值非常方便
6.7:输入模块的指定方法
根据需要使用加载的模块,指定输入哪些方法
const {SourceMapConsumer ,SourceNode} = require('source-map')