1.
let [ foo , [ [ bar ] , baz ] ]=[ 1 , [ [2] , 3] ];
foo //1
bar //2
baz //3
let [ , ,third]=["a","b","c"];
third //c
let [x, ,y]=[1,2,3];
x //1;
y //3;
let [head,...tail] =[1,2,3,4];
head //1
tail //[2,3,4]
let [x,y,...z] =["a"];
x //"a"
y //undefined
结构不成功,都会成undefined
let [foo] =[];
let [bar,foo]=[1];这2种都会结构不成功的,foo都会是undefined
2.不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组,这种情况下,解构依然可以成功
let [x,y]=[1,2,3] x //1 y //2
let [a,[b],d]=[1,[2,3],4] a //1 b//2 d//4
3.如果等号右边的不是数组,那么将会报错
let [foo]=1; let [foo]=false;let [foo]=NAN;let[foo]=undefined; let [foo]=null;let [foo] ={};
4.只要某种数据解构具有iterator接口,都可以采用数组形式的解构赋值
function * fibs(){
let a =0;
let b=1;
while(true){
yield a;
[a,b]=[b,a+b];
}
}
let [first,second,third,fourth,fifth,sixth] =fibs();
sixth //5
6.解构赋值允许指定默认值
let [foo=true] =[];
foo //true
let [x,y="b"] =["a"] x//a y //b
7.es6内部使用严格相等运算符(===),判断一个位置是否有值,所以,只有当一个数组成员严格等于undefined,默认值才会生效
let [x=1]=[undefined] x //1
let [x=1]=[null] x// null不严格等于undefined
8.
9.默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x=1,y=x]=[]; x//1 y//1
let [x=1,y=x]=[2]; x//2 y//2
let [x=1,y=x]=[1,2] x//1 y //2
let [x=y,y=1]=[]; 报错
10.解构不仅可以用于数组,还可以用于对象(对象的属性没有次序,变量必须与属性同名,才能取到正确的值)
let {foo,bar}={foo:"aaa",bar:"bbb"}; foo//aaa bar//bbb
let {baz}={foo:"aaa",bar:"bbb"} baz//undefined
如果变量名与属性名不一致,必须写成?这样
let {foo:baz} ={foo:"aaa",baz:"bbb"} baz //aaa
let obj ={first:'hello',last:'word'}
let {first:f,last:1}=obj;f //hello l //world
11.对象的解构赋值的内部机制,是先找到同名的属性,然后再赋给对应的变量,真正被赋值的是后者,而不是前者
let {foo:baz}={foo:"aaa",bar:"bbb"} baz //aaa foo erro bar //erro
12.与数组一样,解构也可以用于嵌套解构的对象
let obj ={
p:[
'hello',
{y:'world'}
]
};
let {p,p:[x,{y}]}=obj;
x //hello y //world p //["hello",{y:"world"}]
13.
14.对象嵌套赋值
let obj ={};
let arr =[];
({foo:obj.prop,bar:arr[0]}={foo:123,bar:true}) obj //prop:123 bar //[true]
15.对象的解构也可以指定默认值
let {x=3}={} x//3
let {x,y=5}={x:1} x //1 y //5
let {x:y=3}={} y// 3 x//error
let {x:y=3}={x:5} x//erro y//5
let{message:msg='something went wrong'}={}
msg //something went wrong
16.默认值生效的条件是,对象的属性严格等于undefined
let {x:3}={x:undefined} x//3
let {x=3} ={x:null} x //null
17.如果解构失败,变量的值等于undefined,
let {foo}={bar:'baz'} foo //undefined
如果解构模式是嵌套的对象,而且对象所在的父属性不存在,那么将会报错
let {foo:{bar}}={baz:'baz'} 等号左边对象的foo属性,对应的是一个子对象,该子对象的bar属性,解构时会报错,因为foo这时候等于undefined,再取子属性就会报错
let _basd={x:'baz'}
console.log(_basd.x) //baz
18.
19.由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构
let arr=[1,2,3] ;
let {0:first,[arr.lenght-1]:last}=arr first //1 last//3
20.字符串的解赋值
const [a,b,c,d,e]='hello' a//h b//e c //l
21.类似数组的对象都有一个length属性
let {length:len}='hello'; len //5
22.数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象
let {toString:s}=123;
s ===Number.prototype.toString //true
let {toString:s}=true;
s ===Boolean.prototype.toString //true
23.等号右边的值不是对象或数组,就先将其转换为对象,由于undefined null无法转为对象,所以对他们进行解构赋值都会报错
let {prop:x} =undefined; error
let {prop:y} =null; error
24.函数参数的解构赋值
function add([x,y]){
return x+y;
}
add([1,3]) //4
[[1,2],[3,4]].map([a,b]=>a+b); //[3,7]
25.函数参数的解构也可以使用默认值
function move({x=0,y=0}={}){
return [x,y]
}
move({x:3,y:8}) //[3 8]
move() //[0 0]
move({x:3}) //[3,0]
function move({x,y}={x:0,y:0}){
return [x,y]
}
move({x:3,y:8}) //[3,8]
move({x:3}) //[3,undefined]
move({}) //[undefined,undefined]
move() //[0,0]
26.不能使用圆括号的情况
变量声明语句,函数参数也属于变量声明,赋值语句的模式
27.用途
a.变换变量的值 let x =1;let y=2; [x,y]=[y,x]
b.从函数返回多个值
function example(){
return [1,2,3];
}
let [a,b,c]=example();返回数组
function example(){
return{
foo:1,
bar:2
}
}
let {foo,bar} =example()返回对象
c.函数参数的定义
function f([x,y,z]){...}
f([1,2,3]); //参数是一组有次序的值
function f({x,y,z}){...}
f({z:3,y:2,x:1}) //参数是一组无序的值
d.提取json数据
let jsonData ={
id:42,
status:"ok",
data:[867,5309]
}
let {id,staus,data:number} =jsonData;
id//42 status//"ok" number //[867,5309]
e.函数参数的默认值
f.遍历map结构
const map =new Map();
map.set('first','hello')
map.set('second','world')
for(let [key,value] of map){
console.log(key +'is'+value)
}
//first is hello
//second is world