最优:结构赋值的规则是,只要等号右边的值不是对象或者数组,就先将其转为对象,再匹配更详细规则。由于undefined和null无法转换为对象,所以进行匹配就回报错。
注意事项:变量声明、函数参数、赋值语句模式等不要带圆括号,es6识别不出来是要做结构还是做表达式。
1、数组:左右都是数组(可遍历)
1.1、模式匹配:左右两边格式完全相同,较好理解,直接赋值。
let a=1; //a==1
let [a,b,c]=[1,2,3]; //a==1,b==2,c==3
let[a,[b,c]]=[1,[2,3]]; //a==1,b==2,c==3
1.2、运算符匹配:三点运算符
1.2.1、剩余运算符:剩余的必须写在最后部分
let [a,b,...c]=[1,2,3,4,5]; //a==1,b==2,c==[3,4,5]
1.2.2、拓展运算符:解构数组插入,避免出现直接插入情况
let a=[2,3,4];b=[1,...a,5]; //b==[1,2,3,4,5]
1.3、不完全解构:从左到右匹配完,剩余部分忽略
1.3.1、值不够匹配变量:let [a,b,c]=[1,2]; //a==1,b==2,c==undefined
1.3.2、变量不够匹配值:let [a,b,c]=[1,2,3,4]; //a==1,b==2,c==3
1.4、设置默认值:只要匹配的右边是严格等于undefined,那么左边的默认值就生效。设置的默认值必须是声明过的。
let [x=1]=[undefined]; //x==1
let [x=1]=[null]; //null
let [x=1,y=2]=[3]; //x==3,y==2
let[x=y]=[]; //ReferenceError:y is not defined
2、对象
2.1、直接匹配(实际为通过对象冒号的左边进行匹配,赋值给右边的变量;当没有明确写的时候默认变量和属性相同)
let {foo,bar}={foo:"a",bar:"b"}; //foo=="a",bar=="b";实际生效的是 let {foo:foo,bar:bar}={foo:"a",bar:"b"};
let {a:foo,b:bar}={a:"A",b:"B"}; //foo=="A",bar=="B"
2.2、嵌套匹配:参考第1点,对象层级一样,父层一定要匹配上否则报错,因为undefined是没有子属性的。
let {foo:{a}}={foo:{a:5}}; //foo==undefined,匹配上foo,子对象a==5
let {foo,foo:{a}}={foo:2,foo:{a:5}}; //foo=={a:5},匹配上foo,子对象a==5;先赋值foo=2,再赋值foo={a:5}
let {foo:{a}}={foo:5}; //undefined,不报错,匹配上foo,但是没找到子对象a
let {foo:{a}}={faa:5}; //Cannot destructure property `a` of 'undefined' or 'null'.,报错,匹配不上faa,更不要说.出子对象
2.3、默认值:只要匹配的右边是严格等于undefined,那么左边的默认值就生效。设置的默认值必须是声明过的。
let {x=1}={}; //x==1
let {x=1,y=2}={x:3}; //x==3,y==2
let{x:y=3}={}; //y==3,x只是匹配,不是变量
let{x:y=3}={x:5}; //y==5,x只是匹配,不是变量
let{x:y=s}={}; //ReferenceError: s is not defined
2.4、数组:作为特殊对象进行对象结构:匹配的是下标
let arr=[1,2,3,4];
let {2:a}=arr; //a==3
3、字符串:根据字符串长度结构为数组,匹配规格和数组&对象一样
let=[a,b,c]="abcdefg"; //a=="a",b=="b".c=="c" 根据数组匹配数组
let={0:a,3:b,5:c}="abcdefg"; //a=="a",b=="d".c=="f" 根据数组下标匹配对象
4、数值和布尔值结构:先转换为对象,然后通过原型属性进行匹配
let {toString:s}=123; s===Number.prototype.toString //true
5、函数次数的解构
规则和对象解构一样,不过是讲赋值转成了穿参的形式。
function add([x,y]){return x+y} add([1,2]) //3
function add({x,y}={x:0,y:0}){return [x,y]} ; add() //00 ,如果没给其他赋值那就2个都是0,如果赋值2个就显示赋值的 例如add({x:1,y:2}) return [1,2],只有1个就按规则匹配 例如add(x:1) return [1,undefined]。最核心的思路就是,等号右侧的0,0是给默认值 而不是给变量,可以理解为{x:0,y:0}={}。传参就是我们调用方法的时候给过去。
6、主要用途
6.1、数组顺序调整
6.2、返回多个值:相比之前只能renturn 1个值,现在es6可以返回一个数组或者对象,然后通过结构得到返回的所有数据
function example(){ return [1,2,3]} let [a,b,c]=example(); //a==1,b==2,c==3
6.3、通过函数参数结构进行有序传参(数组匹配)和无序传参(对象匹配)