变量的解构赋值
目录1. 解构赋值
===
解构赋值并不只是用于直接的赋值,更多情况下用于函数之间的传参。比如A函数返回一个对象/数组,那么B函数可以直接使用解构提取A返回的对象/数值中的元素使用,而不用完全接收整个对象/数组
===
-
ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称为解构
-
解构赋值
//传统变量赋值 let a = 1; let b = 2; let c = 3; //解构赋值 let [a,b,c] = [1,2,3];
另一些比较特殊的情况
let [foo,[[bar],baz]] = [1,[[2],3]]; let [,,third] = ["foo","bar","baz"]; let [head,...tail] = [1,2,3,4]; //tail = [2,3,4] let [x,y] = [1,2,3]; //如果解构不成功,变量的值就等于undefined let [bar,foo] = [1]; //bar=1,foo=undefined
-
默认值
解构赋值还允许设置默认值,默认值仅在取不到值(undefined)的情况下生效
let [foo = true] = []; let [x,y = 'b'] = ['a',undefined];
-
解构赋值的条件
只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。反之,只要等号右边不是可遍历结构,那么就会报错
//不报错 let [x,y,z] = new Set(['a','b','c']); //报错 let [foo] = 1; let [foo] = false; let [foo] = undefined; let [foo] = ();
2. 对象的解构赋值
-
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性同名才能取到正确的值
let {foo,bar} = {foo:"aaa",bar:"bbb"}; let {bar,foo} = {foo:"aaa",bar:"bbb"}; //打乱也可以 let {baz} = {foo:"aaa",bar:"bbb"}; //baz为undefined
-
默认值
var {x=3} = {}; var {x,y=5} = {x:1}; var {x:y=3} = {x:5};
-
模式匹配
如果变量名与属性名不一致,就要使用模式匹配
let {first:f,last:l} = {first:'hello',last:'world'};
此时,对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者。
let {foo:baz} = {foo:"aaa",bar:"bbb"}; // baz = 'aaa' // foo = undefined
这里很可能对符号
:
产生混淆,需注意等号左边的:
表示的是匹配模式,等号右边的:
表示的是对象中属性的值
3. 其它解构赋值
- 解构赋值的原则是:只有等号右边的值不是对象或数组,就先将其转换为对象。null和undefined无法被转换为对象,此时就会报错
3.1 字符串解构赋值
const [a,b,c,d,e] = 'hello';
//由于字符串本质是对象,其中有length属性,所以也可以匹配出来
let {length:len} = 'hello'; //len = 5
3.2 数值和布尔值的解构赋值
let {toString:s} = 123;
let {toString:s} = true;
3.3 函数的解构赋值
function add([x,y]){
return x+y;
}
add([1,2]); //3
4. 用途
-
交换变量的值
[x,y] = [y,x]
-
从函数返回多个值
function example(){ return [1,2,3]; } let [a,b,c] = example(); function example2(){ return { foo: 1, bar: 2 }; } let {foo,bar} = example2();
-
函数参数的定义
function f([x,y,z]) {}; f([1,2,3]);
-
函数参数的默认值
function(url,first='a',last='b'){};
-
提取JSON数据
let jsonData = { id:42, status:"ok" }; let {id,status} = jsonData;