ES5中的变量的赋值方式
let a=1;
let b=2,c=3,d=4;
直接指定其值
而在ES6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解析。
数组解析
let [a,b,c]=[1,2,3];
console.log(a,b,c);//1 2 3
本质上,这种写法属于"模式匹配",只要等号两边的模式相同,左边的变量就会被赋予对应的值。
解析不成功时,变量的值都会等于undefined。
let [a]=[];
console.log(a);//undefined
let [b,c]=[1];
console.log(b,c);//1 undefined
如果等号右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错
let [a]=1;
console.log(a);
let [b]=false;
console.log(b);
let [c]=NaN;
console.log(c);
let [d]=undefined;
console.log(d);
let [e]=null;
console.log(e);
let [f]={};
console.log(f);
// 报错:..is not iterable
上面的语句都会报错,因为等号右边的值,要么转为对象后不具备Iterator接口,要么本身就不具备Iterator接口。
事实上,只要某种数据结构具有Iterator接口,都可以采用数组形式的解析赋值
对于Set结构,也可以使用数组的解析赋值。
let [x,y,z]=new Set(['a','b','c']);
console.log(x,y,z);//a b c
fibs()是一个Generator函数,原生具有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();
console.log(first,second,third,fourth,fifth,sixth);//0 1 1 2 3 5
解析赋值允许指定默认值
let [foo]=[];
console.log(foo);//undefined
let [foo=true]=[];
console.log(foo);//true
let [foo=true]=1;
console.log(foo);//1 is not iterable
注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员其值严格等于undefined时,默认值才会生效。
默认值可以引用解析赋值的其他变量,前提是该变量必须已经声明
对象解析
解析不仅可以用于数组,还可以用于对象
let {a,b,c}={a:1,b:2,c:3};
console.log(a,b,c);//1 2 3
对象的解析与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定,而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let {x,c}={a:1,b:2,c:3};
console.log(x,c);//undefined 3
第一个变量没有同名属性,导致取不到值,最后等于undefined.
如果解析失败,变量的值等于undefined
如果变量名与属性名不一致,想要解析,必须写成这样
let {x}={foo:123};
console.log(x);//undefined
let {foo:x}={foo:123};
console.log(x);//123
上面的代码中,foo是匹配的模式,x才是变量,真正被赋值的是变量baz,而不是模式foo。
与数组一样,解析也可以用于嵌套结构的对象。
let obj={
p:['hello',{y:'world'}]
};
let {p:[x,{y}]}=obj;
console.log(x);//hello;
console.log(y);//world
…