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解构赋值 (数组 , 对象)的主要内容,如果未能解决你的问题,请参考以下文章