ES2015中允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,被称为”解构(Destructering)“。
以前,为变量赋值,只能指定值。
1 /** 2 * 以前,为变量赋值,只能直接指定值 3 * **/ 4 let a = 1;//第一种:变量赋值 5 let b = 2; 6 let c = 3; 7 /** 8 * 现在ES2015允许这样:数组和对象 9 * **/ 10 let [a,b,c] = [1,2,3];//第二种:数组的解构赋值 11 let {a,b,c} = { 12 a:1, 13 b:2, 14 c:3 15 };//第三种:json对象解构赋值
本质上,后两种通过解构赋值的写法属于”模式匹配“,只要判定了等号两边的模式相同(解构),左边的变量就会被赋予对应的值即赋值。
数组的解构赋值
上面例子第二种就是数组解构赋值,这是刚好完全解构的情况,还有两种不完全解构的情况:
1 /** 2 * 不完全解构的情况 3 */ 4 { 5 let [a,b,c] = [1,2];//c的值:undefined 6 console.log(a,b,c);//1 2 undefined 7 } 8 9 { 10 let [a,b] = [1,2,3];//右侧多了一个3 11 console.log(a,b);//1,2 12 } 13 14 { 15 let [,,c] = [1,2,3];//c 3 16 console.log(c);//3 17 } 18 /** 19 * 由此例子可以看到当左侧的c没有解构成功时(即右侧的数据结构没有与之对应的部分),那么这个变量的值为undefined 20 * 那么这个变量的值为undefined,我们知道某个值为undefined的时候存在两种情况: 21 * 一种是生命了没有赋值 22 * 另一种是显示赋值为undefined 23 * **/
1 { 2 const [d] = []; 3 console.log(d);//undefined 4 //没有解构成功的变量会被显式赋值为undefined 5 }
当数组内部有嵌套时,解构依然能正常进行:
1 {//可以嵌套 2 let [a,[b,c],d] = [1,[2,3],4]; 3 console.log(a,b,c,d); 4 }
除此之外还允许为解析解构设定默认值,即变量在解构后没有被赋到值(严格来说,应该被赋值为undefined)的情况下允许赋予变量某个默认值:
1 let [foo = true] = []; 2 console.log(foo);//true 3 4 let [x,y="bbb"] = ["a"]; 5 console.log(x,y);//a bbb 6 7 let [x,y= "b"] = ["a",undefined]; 8 console.log(x,y);//a b 9 10 let [x = 4] = [undefined];//在变量有默认值的时候,只有当解构之后赋的值为undefined时,默认值才会生效,否则默认值会被解构之后的值覆盖。 11 console.log(x);//4 12 13 let [x = {a:12}] = [null];//null是对象,不为空。 14 console.log(x);//null
当默认值为表达式时,表达式的求值是惰性的。
1 function f(){ 2 console.log("aaa"); 3 } 4 //let [x] = [1]; 5 //let [y] = []; 6 let [z = f()] = []; 7 let [z1 = f()] = [undefined]; 8 9 let [a = f()] = [1]; 10 11 //console.log(x);//1 12 //console.log(y);//undefined 13 console.log(z,z1);//aaa aaa undefined undefined 当然如果右侧换成[][undefined]的话,f()执行。 14 console.log(a);//1 因为被解构的值是1,所以默认值不会生效,于是f()也就没有必要执行,它也确实没有执行,因为如果执行的话,会打印aaa。 15 //当默认值为表达式时,表达式的求值时惰性的。
默认值还可以引用解构赋值的其他变量,但前提是该变量必须已经声明,即被引用变量必须排在引用变量的前面。
1 //let [x = 1, y = x] = [];//1 1 2 //let [x = 1, y = x] = [2];//2 2 先确定x的值是2 3 //let [x = 1, y = x] = [1,2]; //1 2 4 let [x = y,y = 1] = [];//ReferenceError引用错误 原因:x用到默认值y的时候,y还没有被声明。 5 6 console.log(x,y);
对象的解析赋值
原文:https://www.cnblogs.com/liubeimeng/p/10689075.html