arr.reduce()妙用:解决根据一个字符串读取多层嵌套对象属性的问题

写node过程中遇到这么一个问题,要根据一个字符串str="userInfo.uname.firstName"来判断一个前端通过body对象传参是否缺少必传参数,例如前端通过body传参如下:

{
    userInfo: {
        uname: {
            firstName: 'Wu',
            lastName: 'Dan'
        },
        age: 28
    }
}

首先想到的是通过把 str 分割成数组 [ 'userInfo', 'uname', 'firstName' ],然后通过递归依次读取 body['userInfo']['uname']['firstName'] 的方式来判断有没有缺少 firstName 属性,查询过程中突然发现 reduce 这个冷门的 js 方法可能可以简化这个过程。

首先来了解一下 reduce 方法,官方给出的解释:

定义和用法

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

reduce() 可以作为一个高阶函数,用于函数的 compose。

注意: reduce() 对于空数组是不会执行回调函数的。

语法

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

参数

参数描述
function(total,currentValue, index,arr)必需。用于执行每个数组元素的函数。
函数参数:
参数描述
total必需。初始值, 或者计算结束后的返回值。
currentValue必需。当前元素
currentIndex可选。当前元素的索引
arr可选。当前元素所属的数组对象。
initialValue可选。传递给函数的初始值

可以看出官方推荐的用法是使用这个累加器可以方便的计算一个数组元素的和,通过 return 可以把每次迭代的值返回给total作为下一次的初始值,如果我们 return 一个对象的话,不就可以依次读取多层嵌套的对象的属性了吗? 

上代码:

// 现在有一个需要判断的字符串 'userInfo.uname.firstName',以及一个已有的对象 body{}
let str = 'userInfo.uname.firstName'
if(str.indexOf('.')){
    let attrArr = str.split('.')
    // prev 表示初始值或上一次 return 的值, cur 表示当前迭代器里的元素,从左到右依次迭代
    attrArr.reduce((prev, cur) => {
          // 如果 对象[属性] 存在,那么返回前一次 对象[属性],相当于往嵌套走了一层
          if(!!prev[cur]){
            return prev[cur]
          }else{
            throw new Error(cur + '不存在')
          }
    }, body)   // 这里的 body 就是需要判断的对象
}

可以判断出 body 下的 userInfo uname firstName 任何一个嵌套层级缺少属性都会抛出错误.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
arr.reduce一个数组方法,它用于将数组中的每个元素进行累积计算,最终返回一个值。它接受一个回调函数和一个初始值作为参数。回调函数有四个参数:previousValue(上一次回调函数的返回值)、item(当前元素的值)、index(当前元素的索引)、arr(原数组)。初始值是可选的。 在执行reduce方法时,它会从数组的第一个元素开始,调用回调函数。回调函数返回的值将作为下一次调用的previousValue参数。这样,reduce方法会依次处理数组的每个元素,最终返回一个累积计算的结果。 可以通过reduce方法来实现各种累积计算,例如求和、求平均值、拼接字符串等。具体的计算逻辑需要在回调函数中实现。 总结一下,arr.reduce用于对数组元素进行累积计算,并返回一个值。它接受一个回调函数和一个可选的初始值参数。回调函数在每次计算时被调用,并返回一个值作为下一次计算的输入。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JS中 reduce() 的用法](https://blog.csdn.net/weixin_30633949/article/details/102155869)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [js【详解】arr.reduce() 数组缩减](https://blog.csdn.net/weixin_41192489/article/details/116661854)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值