ES6解构赋值 (数组 , 对象)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6解构赋值 (数组 , 对象)相关的知识,希望对你有一定的参考价值。

参考技术A ES6允许从数组中提取值,按照对应位置 对变量赋值。对象也可以实现解构。

1.数组解构

1.对象解构
允许 我们使用变量的名字匹配对象的属性 匹配成功将对象属性的值赋值给变量

对象解构 起别名

ES6--解构

ES6解构赋值
 
1、数组和对象: 本质上是 “模式匹配” 参考下面"对象解构赋值"的例子来理解
2、解构赋值的规则: 只要等号右边的值不是对象或数组(类数组),就先将其转为对象
3、undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错
4、根据 “ECMAScript 6 入门 阮一峰” 的讲解以及部分例子进行理解
 
一、数组解构
 
无默认值
1   {
2     let [a]=[1,2]; // a=1 普通解构 
3     let [b] = []; // b=undefined 解构失败 无默认值 因此相当于定义一个没有显式赋值的变量: let b;
4 
5     let c=3,d=4;
6     [c,d]=[d,c]; // c=4 d=3 普通解构
7 
8   }

 

有默认值

 1   {
 2     // 有默认值
 3     let [e=5]=[null]; // e=null 数组成员为 null 解构成功 默认值不生效 
 4     let [f=5]=[undefined]; // f=5 数组成员严格等于undefined 解构失败 默认值生效 
 5 
 6     // 默认值为表达式时惰性求值 即只有在用到的时候才求值
 7     function func(){return 6}
 8     let [g=func()]=[7]; // g=7 等号右边有对应值 解构成功 此时 g 就不会去获取默认值 因此 func() 也就不会执行
 9     let [h=func()]=[]; // h=6 解构失败 有默认值 此时表达式才会开始执行 即 func() 执行     
10   }

 

数组其他解构

 1   {
 2     let [k,[[l], m]] = [9, [[10], 11]]; // k=9 l=10 m=11 嵌套解构
 3 
 4     // 引用解构赋值的其他变量 但该变量必需已经声明
 5     let [i=8,j=i]=[]; // h=8 i=8  前面先声明变量 i 然后赋值为 8 ,后面声明 j 然后赋值为 i ,此时 i 已经声明 解构成功
 6     // let [j=i,i=8]=[]; 报错 解析: 前面先声明变量 j 然后赋值为 i ,此时 i 还没有声明 解构失败
 7 
 8     let [,,n,...o] = [12, 13, 14,15,16]; // n=14 o=[ 15, 16 ] 解构特定的值 (想要获取数组最后一个元素,参考下面对象的解构赋值)
 9     // " , " 分隔开等号左右两边对应要解构的值," ... " 获取剩余的值到对应变量,若剩余值为空,则返回空数组
10   }

 

二、对象解构

对应变量名

1   {
2     let {b,a} = {a:"aaa",b:"bbb"}; // a=aaa b=bbb 对象赋值 必需对应属性名 与属性名次序无关
3     let {c}={d:"ddd"}; // c=undefined 没有对应属性名 即等号右边的对象找不到名称为 c 的属性,因此相当于 let c;    
4     let {x, y = 5} = {x: 1}; // x=1 y=5 x 获取等号右边的对应值 y 获取默认值
5   }

 

自定义变量名

1     let {e:nameE,f:nameF}={e:"eee",f:"fff"}; // nameE=eee nameF=fff 输出 e f 会报错
// 解析: 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量 真正被赋值的是后者,而不是前者
// 此处 e、f 是匹配模式 nameE、nameF 才是变量 真正被赋值的是变量而不是匹配模式
// 即左边根据 e、f 到右边的对象中找名称为 e、f 的属性,找到后将右边对应的属性的值付给左边对应的变量 nameE 和 nameF
// nameE、nameF 这两个变量获取对应的值输出自然成功,但是左边的 e、f 用来是匹配的匹配模式 根本没有定义名称为 e、f 的变量,输出自然会报错
// 匹配模式、变量、属性的区别: 等号左边--》 冒号前为匹配模式 冒号后为变量 逗号隔开的即为不同的属性
// 因此实际上 let {b,a} = {a:"aaa",b:"bbb"}; 为 let {b:b,a:a} = {a:"aaa",b:"bbb"}; 的简写模式
 
比如下面例子中最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量
 1     const node = {
 2       loc: {
 3         start: {
 4           line: "line",
 5           column: "column"
 6         }
 7       }
 8     }; 
 9   let { loc, loc: { start }, loc: { start: { line }} } = node; 
10   // loc=Object { start: {…} } start=Object { line: "line", column: "column" } line=line
 

数组本质是特殊的对象,因此可以对数组进行对象属性的解构

1     let arr = [1, 2, 3, 4, 5];
2     let {0 : firstValue, [arr.length - 1] : lastValue} = arr; // 获取数组第一个以及最后一个元素

 

其他解构

 1 {
 2   // 如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错
 3   // let {foo: {bar}} = {baz: ‘baz‘}; 
 4   // 想象一个对象 let obj={a:111} 然后要求输出 obj.b 毫无疑问这样会报错
 5 
 6   // 对已经声明的变量结构赋值    
 7     // 错误写法
 8     // let g;
 9     // {g}={g:"ggg"};
10     // 解析: JavaScript 引擎会将{g}理解成一个代码块,从而发生语法错误
11 
12     // 正确写法
13     let g;
14     ({g}={g:"ggg"});    
15 
16     ({} = ‘hhh‘); // 没什么用但是语法上行得通
17   }

 

三、字符串、数值、布尔值的解构赋值

 1   {
 2     // 字符串 解构赋值时字符串被转换成了一个类似数组的对象
 3     let[a,b,c]=‘hello‘;
 4     // console.log(a,b,c);
 5 
 6     // 数值 解构赋值时 如果等号右边是数值和布尔值 则会先转为对象
 7     let {toString: d} = 123;
 8     d === Number.prototype.toString // true
 9 
10     // 布尔值
11     let {toString: e} = true;
12     e === Boolean.prototype.toString // true
13   }
 
、函数参数的解构赋值
 
给函数参数中的变量赋默认值
1     function funcOne({x = 0, y = 0} = {}) {
2       return [x, y];
3     }
funcOne({x: 3, y: 8}); // [3, 8] 解析: 是否有参数传进来 --》 有 --》 函数参数 {x = 0, y = 0}={x: 3, y: 8} 进行解构
funcOne({x: 3}); // [3, 0] 解析: 是否有参数传进来 --》 有 --》 函数参数 {x = 0, y = 0}={x: 3} 进行解构
funcOne({}); // [0, 0] 解析: 是否有参数传进来 --》 有 --》 函数参数 {x = 0, y = 0}={} 进行解构
funcOne(); // [0, 0] 解析: 是否有参数传进来 --》 无 --》 函数参数为: {x = 0, y = 0} 变量 a=0 b=0 没有解构
 
给函数参数赋默认值
1     function funcTwo({x, y} = { x: 0, y: 0 }) {
2       return [x, y];
3     }
funcTwo({x: 3, y: 8}); // [3, 8] 解析: 是否有参数传进来 --》 有 --》 函数参数 {x, y}={x: 3, y: 8} 进行解构
funcTwo({x: 3}); // [3, undefined] 解析: 是否有参数传进来 --》 有 --》 函数参数 {x, y}={x: 3} 进行解构
funcTwo({}); // [undefined, undefined] 解析: 是否有参数传进来 --》 有 --》 函数参数 {x, y}={} 进行解构
funcTwo(); // [0, 0] 解析: 是否有参数传进来 --》 无 --》 函数参数为: {x, y} = { x: 0, y: 0 } --》 进行解构
 
给函数传递参数影响的是:函数参数的默认值
1    [1, undefined, 3].map((x = ‘yes‘) => x); // [ 1, ‘yes‘, 3 ]
/*
解析:对该函数的理解如下:
[1, undefined, 3].map(function({x = ‘yes‘}){
return x
});
即:x=‘yes‘ 是给函数参数中的变量赋默认值(注意与 “给函数参数赋默认值” 的区别)
 
传入 1 时: 相当于 let {x=‘yes‘}={x:1} --》 解构 x=1 ,传入 3 时与传入 1 时类似
function({x = ‘yes‘}={ x : 1 }){
return x
}

传入 undefined 时: 相当于 let {x=‘yes‘}={x:undefined} --》 解构 x=yes
function({x = ‘yes‘}={ x : undefined }){
return x
}
*/
 

以上是关于ES6解构赋值 (数组 , 对象)的主要内容,如果未能解决你的问题,请参考以下文章

260 ES6解构赋值

JavaScript ES6 - 解构赋值

JavaScript ES6 - 解构赋值

JavaScript ES6 - 解构赋值

ES6 解构赋值

ES6基础-变量的解构赋值