• ES2020-23简单易懂又实用的精选特性讲解 ✨✨日常开发必备干货!✨✨


    ES6以来,越来越多的新特性被加入到规范当中。有一些特性(如promise扩展运算符箭头函数)会在实际的业务开发中起到很大作用,但是也有一些特性(如generatorSymbolMap)在日常业务开发中并没有很必要的实际作用,徒增开发者的学习成本。针对上述情况,笔者重点挑了ES2020ES2023简单实用的一些特性,结合实际业务场景和代码做详细的讲解,帮助开发者利用新特性,实打实的提高日常开发效率。

    如果这篇文章能给您带来一点点的帮助的话,麻烦移动下鼠标点个❤️赞❤️吧!您的点赞会给笔者带来更新的持续动力!

    Array.at() (更方便地提取数组下标value)

    先让我们来看下他的用法:

    const array1 = [5, 12, 8, 130, 44];
    console.log(array1.at(2)) //8
    console.log(array1.at(3)) //130 
    
    • 1
    • 2
    • 3

    各位读者可能注意到了,at其实和日常的.或者[]一样,获取数组下标的value值,那他有啥用呢,为什么不直接用.或者[]呢?

    答案就是:at可以从末尾倒数获取下标vaule值。

    这在不知道数组长度的情况下是非常实用的特性。直接上对比代码:

    //`.`或者`[]`方式
    const array1 = res.data?.priceList || [];
    //获取最后一项价格
    const lastItemIndex = array1.length - 1;
    console.log(array1[lastItemIndex])
    
    //at方式
    const array1 = res.data?.priceList || [];
    //获取最后一项价格
    console.log(array1.at(-1)) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    可以看到,此时at方式可以更快,更方便的取出最后一项,再也不需要计算数组长度了!是不是很实用呢!

    空值合并运算符(更优秀的假值判断)

    我们从后端接口获取数据时,经常会遇到后端缺字段的情况,导致前端不得不去做空值兼容,防止后端不给字段,例如我们需要获取商品价格时,我们会写:

    const price = res.data?.price || '暂无标价' 
    
    • 1

    但是其实这种做法是有问题的,显然易见,如果一个免费商品的价格为0的话,我们这里的||就会产生一个bug。而且习惯了||写法的时候,很容易会忽略这个潜在问题。等到bug产生的时候,我们只能改成:

    const price = (res.data?.price === null || res.data?.price === undefined) ? '暂无标价' : res.data?.price 
    
    • 1

    显然这个代码又长,可读性也差。有没有更好的判断字段为空的方式呢,有,那就是空值合并运算符??

    const price = res.data?.price ?? '暂无标价' 
    
    • 1

    代码一下子变的精简舒服多了!

    可以看到,空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。

    在一些业务场景下,可以取代||,用来规避使用||来为某些变量设置默认值,可能会遇到意料之外的行为。(例如,''0

    可选链Optional Chaining(更精简的判断嵌套对象的空值key)

    还是以后端接口为例,我们经常会遇到后端返回给我们一个多层级嵌套的对象数据,例如:

    {resuslt: {data: {userInfo: {name: ''}}}
    } 
    
    • 1
    • 2

    我们需要像这样获取name的值:

    const name = res.result.data.userInfo.name 
    
    • 1

    随着后端的日常接口崩溃,返回值直接变成了:

    {resuslt: {}
    } 
    
    • 1
    • 2

    于是乎,出现了我们前端的经典报错: Cannot read properties of undefined。随着js的进程阻塞,后端开始甩锅前端没有做兼容判断,于是乎,我们背着锅写下了兼容代码:

    const name = ''
    if(res.result && res.result.data && res.result.data.userInfo && res.result.data.userInfo.name) {name = res.result.data.userInfo.name
    } 
    
    • 1
    • 2
    • 3

    代码又长又冗余,接下来,就是可选链Optional Chaining出场了:

    const name = res?.result?.data?.userInfo?.name || '' 
    
    • 1

    上面的代码和之前又长又冗余的代码效果是一样的!是不是非常精简呢?顺着代码我们可以发现,可选链Optional Chaining的含义是:

    可选链操作符 ( ?. ) 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空 (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是undefined

    而且它还可以和函数结合使用,与函数调用一起使用时,如果给定的函数不存在,则返回undefined。这样我们就可以更好避免日常开发中,变量不是function的情况:

    const name = instance.apiFunc
    const res = name?.getResult('param') 
    
    • 1
    • 2

    Array.group()快速分类组合数组(需依赖babel)

    这也是一个非常实用的特性,我们举一个比较常见的实际业务场景为例: 此时我们作为电商公司正值618活动,全国各地有很多人买了我们的商品,后端统计了很多用户的购买信息,包括商品名称、价格、下单所在省份等。于是乎,我们数据库有里有了以下的数据:

    const orderList = [{nickName: 'steven',productName: '西瓜',price: 29,province: 'henan',
    },{nickName: '杨超越',productName: '杨梅',price: 22,province: 'shanxi',
    },{nickName: '范明',productName: '苹果',price: 19,province: 'dongbei',
    },{nickName: '倪虹洁',productName: '桃子',price: 88,province: 'shanxi',
    },{nickName: '杨超越2号',productName: '西瓜',price: 29,province: 'henan',
    },{nickName: '杨超越3号',productName: '杨梅',price: 22,province: 'shanxi',
    },{nickName: '范明2号',productName: '苹果',price: 19,province: 'dongbei',
    },{nickName: '倪虹洁2号',productName: '桃子',price: 88,province: 'shanxi',
    }] 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    此时来了一个需求,618快结束了,我们需要统计各个省份的购买力,也就是要从省份角度统计出各个省份的购买人数,比如:shanxi省多少人买了,dongbei省多少人买了。完成这个需求传统模式下我们需要这样做:

    // 参考上面orderList
    const orderList = [...]
    
    const provinceObj = {}
    
    for (let index = 0; index < orderList.length; index++) {const element = orderList[index];const provinceKey = element.provinceconsole.log('provinceKey', provinceKey);// key值存在就pushif (provinceObj[provinceKey]) {provinceObj[provinceKey].push(element)} else {// key值不存在就新建一个key和valueprovinceObj[provinceKey] = [element]}
    }
    //console.log(provinceObj)
    {"henan":[{"nickName":"steven","productName":"西瓜","price":29,"province":"henan"},{"nickName":"杨超越2号","productName":"西瓜","price":29,"province":"henan"}],"shanxi":[{"nickName":"杨超越","productName":"杨梅","price":22,"province":"shanxi"},{"nickName":"倪虹洁","productName":"桃子","price":88,"province":"shanxi"},{"nickName":"杨超越3号","productName":"杨梅","price":22,"province":"shanxi"},{"nickName":"倪虹洁2号","productName":"桃子","price":88,"province":"shanxi"}],"dongbei":[{"nickName":"范明","productName":"苹果","price":19,"province":"dongbei"},{"nickName":"范明2号","productName":"苹果","price":19,"province":"dongbei"}]
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    用没有更快更优雅的方法呢,有!那就是 Array.group!!接下来我们再看下最新的做法:

    const provinceObj = orderList.group( ({ province }) => province ); 
    
    • 1

    一行代码搞定!是不是既优雅又实用呢!

    总结

    我们此次一共介绍了_Array.at()_ 、空值合并运算符Array.group()可选链Optional Chaining 4种实用新特性。

    如果这几个特性能给您带来一点点的帮助的话,麻烦移动下鼠标点个❤️赞❤️吧!您的点赞会给笔者带来更新的持续动力!

  • 相关阅读:
    java毕业生设计圆梦酒店管理系统计算机源码+系统+mysql+调试部署+lw
    基于STM32和阿里云的智能台灯(STM32+ESP8266+MQTT+阿里云+语音模块)
    docker + miniconda + python 环境安装与迁移(详细版)
    Java字符串(String类)
    np.nan, np.isnan, None, pd.isnull, pd.isna 整理与小结
    【JavaWeb】登录页面记住密码,账号或密码错误
    微软官方操作系统(需空U盘)
    24---WPF缓存
    有什么好用的站内搜索SaaS能帮网站实现站内搜索功能?
    unigui点击按钮后弹出悬浮窗,几秒钟后关闭
  • 原文地址:https://blog.csdn.net/web2022050903/article/details/126115224