ES6中的解构赋值,在我的理解来看,就是把一个类型的数据分解构造,然后把值赋给另个一个同样分解了构造的变量。下面是几种类型的解构赋值
一.数组的解构赋值
数组的解构赋值可以将等号右边对应位置的数值赋值给等号左边对应位置的变量
let [a,b,c]=[1,2,3];
a;//1
b;//2
c;//3
如果等号右边的数组长度小于左边数组的长度,就会出现解构不成功的情况,没有对应值的变量会被赋值为undefined,即使它之前有值。而如果等号右边数组的长度大于左边数组的长度,就会出现部分解构的情况,会把等号右边的数组的前几个值赋值给等号左边的数组中的变量。
let [a,b,c]=[1,2];
a;//1
b;//2
c;//undefined
let [a,b,c]=[1,2,3,4];
a;//1
b;//2
c;//3
上面的情况虽然有的变量会被赋值为undefined,但是至少没有报错,如果等号右边为不可遍历的结构,那么就会报错(转为对象后没有Iterator 接口,或者本身就没有Iterator 接口)Set和Map可以放在数组结构赋值的右边。
let [foo] = 1; //Uncaught TypeError: 1 is not iterable
let [foo] = false; //Uncaught TypeError: false is not iterable
let [foo] = NaN; //Uncaught TypeError: NaN is not iterable
let [foo] = undefined; //Uncaught TypeError: undefined is not iterable
let [foo] = null; //Uncaught TypeError: null is not iterable
let [foo] = {}; //Uncaught TypeError: {} is not iterable
同时,结构赋值允许使用默认值,如果变量严格等于undefined时,就会使用默认值,如果是null,是不会使用默认值的
var [a,b=2]=[1];
console.log("a:"+a+"b:"+b);//a:1b:2
var [a,b=2]=[1,undefined];
console.log("a:"+a+"b:"+b);//a:1b:2
var [a,b=2]=[1,null];
console.log("a:"+a+"b:"+b);//a:1b:null
如果默认值是一个表达式的话,那么只有在用到该默认值时才会执行该表达式
function fn(){
console.log('aaa');
}
let [a=fn()]=[1];
在上面的代码中,因为a会被赋值为1,默认值没有使用,所以里面的console语句没有执行。
二.对象的解构赋值
在数组的解构赋值中,变量和值的位置是一一对应的,但是在对象中,值是不用按照一定顺序的,因为对象的解构赋值时通过找到相同的键名,然后给对应的键名键值,达到赋值的结果。
let {a,b}={a:1,b:2};
a;//1
b;//2
let {c,d}={d:4,c:3};
c;//3
d;//4
数组是特殊的对象,可以对数组使用对象的解构赋值,对应的属性名是索引
var {0:a,1:b,2:c}=[1,2,3];
a;//1
b;//2
c;//3
可以把解构赋值和扩展运算符结合来使用
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
这里使用扩展运算符可以把除了对应赋值外的值合为一个对象赋给扩展运算符后的变量,若没有剩余的值,则扩展运算符后的变量被赋一个空对象。
var {x,y,...z}={x:3,y:4}
x//3
y//4
z//{}
要注意的是,扩展运算符必须放在最后的位置,否则会报错,在同一个解构赋值中使用两个扩展运算符也会报错,因为使用两个扩展运算符必然就会有一个扩展运算符不在最后的位置,从下面代码中浏览器报的错就可以看出来了。
var {x,...y,z}={x:3,y:4,a:1,b:2}
//Uncaught SyntaxError: Rest element must be last element
var {x,...y,...z}={x:3,y:4,a:1,b:2}
//Uncaught SyntaxError: Rest element must be last element
三.字符串的解构赋值
字符串的解构赋值是将字符串拆成一个个字符,对应赋值,使用对象的解构赋值来对字符串进行解构赋值,可以获得字符串的长度
let [a,b,c]='str';
a;//"s"
b;//"t"
c;//"r"
let {length:len}='str';
len;//3
这里可以通过解构赋值的规则来理解,只要等号右边的值不是对象或者数组,就先将其转为对象,而字符串对象有length属性,所以这里是先找到了'str'的length属性,将其值3赋值给len。
四.数值和布尔值的解构赋值
和字符串一样,数值和布尔值也是先转化为对象,然后找到对应的属性值进行赋值。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
解构函数的应用
1.交换变量的值
var a=1;
var b=2;
console.log("a:"+a+" b:"+b);//a:1 b:2
[a,b]=[b,a];
console.log("a:"+a+" b:"+b);//a:2 b:1
2.从函数中返回多个值
function fn(){
return [1,2,3,4];
}
var [a,b,c,d]=fn();
a;//1
b;//2
c;//3
d;//4
3.传入无序的函数参数
function fn({a,b}){
console.log("a:"+a+" b:"+b);
}
fn({b:2,a:1});//a:1 b:2
4.获取json对象中的数据
var json={
user:"me",
id:111
}
var {user,id}=json;
console.log("user:"+user+" id:"+id);//user:me id:111
参考自阮一峰的《ECMAScript6入门》