一文读懂ES6的解构与赋值

1、什么是解构赋值?

ES6 新增了对象解构语法,简单地说,对象解构就是使用与对象匹配的结构来实现将数组中的值或对象的属性取出,赋值给其他变量。解构赋值在处理后台接口返回数据中使用的非常广泛,下面是两个解构赋值的基础例子:

arduino 复制代码
 // 对象
 const obj = { a: 1, b: 2 };
 const { a, b } = obj;  // a=1, b=2
 
 // 数组
 const arr = ["red", "yellow", "green"];
 const [one, two, three] = arr;  // one="red", two="yellow", three="green"
 console.log(one)

objarr本质上同属于对象,二者解构的语法形式上的区别仅在于花括号和中括号,但实际上数组解构是从数组中按照顺序提取元素,并将它们分配给变量。而对象解构从对象中根据属性名提取值,并将它们分配给变量。数组解构基于位置,而对象解构基于属性名,在对象中查找匹配的属性名。

所以,以上例子可以理解为从对象obj中解构出属性名为ab的属性值,再通过const方式声明同名变量进行承接赋值,另外一个数组例子也是类似的,只不过解构赋值时是对应的索引位置。

2、设置解构默认值

每个解构属性都可以有一个默认值,并且默认值可以是一个表达式

当属性不存在或值为undefined时,将使用默认值

而属性值为null时,则不使用默认值而是使用null

ini 复制代码
 const [a = 1] = []; // a is 1
 const { b = 2 } = { b: undefined }; // b is 2
 const { c = 2 } = { c: null }; // c is null
 const { d = console.log('d is undefined') } = { d: undefined }; // d is undefined
3、解构变量的赋值/重命名

实际开发中,通常我们从数据中直接解构赋值获取的变量名不一定是我们想要的,所以可以采取加一个冒号进行重新命名的方式,这种重命名方式本质是将解构出来的变量重新赋值给一个新的变量。

css 复制代码
 // 从对象 o 中获取名为 p 的属性,并将其赋值给名为 foo 的局部变量。
 const obj = { p: 1, q: 2 }
 const { p: foo } = obj 
 console.log(foo); // 1
 ​
 // 解构对象中变量a的值赋值给默认值为10的局部变量A,解构对象中变量b的值赋值给默认值为10的局部变量B
 const { a: A = 10, b: B = 5 } = { a: 3 };
 console.log(A); // 3
 console.log(B); // 5
4、多层嵌套解构与解构数组中指定索引

如1中所述,对象解构就是使用与对象匹配的结构来实现将数组中的值或对象的属性取出,所以对于多层结构,我们也要在左侧构造出相同的结构,那下面这个例子中,我们要如何通过解构获取到变量cover呢?

css 复制代码
 const data = {
   code: "000000",
   list: [
     {
       id: '12345',
       listUrls: [
         { cover: 'https://xxx.com', url: 'https://yyy.com' },
       ]
     },
   ],
 }

虽然看着有点复杂,但只需关注两点..

1、套了多少层分别是什么?

2、是对象的话关注属性值;是数组的话关注索引位置

kotlin 复制代码
 // 1、首先建立同样的数据结构,三层对象两层数组
 const {[{[{}]}]} = data
 
 // 2、然后再关注对象结构中有用到的属性名,无需关注位置先填到对象结构中去,注意一点,因为是多层结构所以需要通过向下赋值才能把解构出来的值传递下去,所以不要漏掉冒号
 const { list: [{ listUrls: [{ cover }] }] } = data
 
 // 3、最后检查数组结构,关注所用的索引和我们的有没有对应上,发现:list数组中用到的是0号位,listUrls中有用到的也是0号位,而在我们写的解构结构中的数组内,正好也都是使用的0号位,那么就不需要做什么改动了,直接打印看下结果!
 console.log(cover);  // https://xxx.com

基于上面例子,会想到如果不是解构0号位置的变量又该怎么做?可以用空来占位要忽略的位置,举例如下:

ini 复制代码
 const props = [
   { id: 1, name: "Fizz" },
   { id: 2, name: "Buzz" },
   { id: 3, name: "FizzBuzz" },
 ];
 const [, , { name }] = props;
 console.log(name); // "FizzBuzz"

那么把之前的例子做一下小调整,同样去解构那条不为空的cover

css 复制代码
 const data = {
   code: "200",
   list: [
     {
       id: '',
       listUrls: [
         { cover: '', url: '' },
       ]
     },
     {
       id: '12345',
       listUrls: [
         { cover: '', url: '' },
         { cover: '', url: '' },
         { cover: 'https://xxx.com', url: 'https://yyy.com' },
       ]
     },
   ],
 }

发现相比之前两个数组分别从0号索引位置变成了1号和2号位置,那么相比之前在数组里面多加下逗号忽略不要的位置即可:

kotlin 复制代码
 const { list: [, { listUrls: [, , { cover }] }] } = data  // https://xxx.com

如果不了解,可能乍一看const { list: [, { listUrls: [, , { cover }] }] } = data会有点懵,这是解构吗?这解的什么鬼,但实际了解了之后发现其实不难。

5、思考

在实际开发中,对于很多层嵌套结构的数据,比如后台透传一些算法数据时,结构会套的很深,然而其实很少使用解构去做,如果使用也只做必然存在的外面一层或两层中的变量,除了多层嵌套解构复杂的原因外,更实际的原因在于当使用多层解构时,如果中间变量有缺失,会报错并中止代码执行,所以可选链(?.)这种方式会用的更多一些 ~

如果对解构赋值还有感兴趣的小伙伴可以移步mdn官网做进一步了解:developer.mozilla.org/zh-CN/docs/...)

相关推荐
○陈3 分钟前
vue2面试题10|[2024-11-24]
前端·javascript·vue.js
米奇妙妙wuu4 分钟前
react实现模拟chatGPT问答页
前端·react.js·chatgpt·前端框架
在荒野的梦想7 分钟前
Vue-TreeSelect组件最下级隐藏No sub-options
前端·javascript·vue.js
田本初1 小时前
浏览器缓存与协商缓存
前端·javascript·缓存
类人_猿2 小时前
ASP.NET Web(.Net Framework) Http服务器搭建以及IIS站点发布
前端·iis·asp.net·.net·http站点服务器
组态软件5 小时前
web组态软件
前端·后端·物联网·编辑器·html
前端Hardy6 小时前
HTML&CSS:MacBook Air 3D 动画跃然屏上
前端·javascript·css·3d·html
cnsxjean8 小时前
SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传
java·前端·spring boot·分布式·后端·中间件·架构
ZL_5679 小时前
uniapp中使用uni-forms实现表单管理,验证表单
前端·javascript·uni-app
沉浮yu大海9 小时前
Vue.js 组件开发:构建可重用且高效的 UI 块
前端·vue.js·ui