es6知识点7-自备使用

es6知识点7-自备使用 这一组很贴近日常业务代码尤其是对象遍历和统计汇总。19.Object.keys / Object.values / Object.entries这三个方法主要用于遍历对象。假设constuser{id:1,name:张三,age:20}19.1Object.keys()拿对象的所有 keyconstkeysObject.keys(user)console.log(keys)结果[id,name,age]所以Object.keys(user)你可以理解成把对象的属性名拿出来组成数组。实战中经常这样遍历Object.keys(user).forEach(key{console.log(key,user[key])})输出id 1 name 张三 age 2019.2Object.values()拿对象所有 valueconstvaluesObject.values(user)console.log(values)结果[1,张三,20]也就是只要值不要属性名比如constscores{chinese:80,math:90,english:85}可以constvaluesObject.values(scores)console.log(values)结果[80,90,85]后面就可以求和consttotalvalues.reduce((sum,item)sumitem,0)19.3Object.entries()这个最实用。它同时拿key value例如constentriesObject.entries(user)console.log(entries)结果[[id,1],[name,张三],[age,20]]所以可以这样Object.entries(user).forEach(([key,value]){console.log(key,value)})这里又用到了我们之前讲过的[key,value]数组解构。19.4 实战构造查询参数比如constqueryParams{name:张三,status:,age:null,pageNum:1}你想删除空参数Object.keys(queryParams).forEach(key{if(queryParams[key]||queryParams[key]null||queryParams[key]undefined){deletequeryParams[key]}})最后{name:张三,pageNum:1}这类代码在请求参数处理里很常见。19.5 实战对象转数组比如后台返回状态统计conststatusCount{WAIT_REPAIR:5,REPAIRING:3,COMPLETED:12}前端图表可能需要[{status:WAIT_REPAIR,count:5},{status:REPAIRING,count:3},{status:COMPLETED,count:12}]可以constlistObject.entries(statusCount).map(([status,count]){return{status,count}})简写constlistObject.entries(statusCount).map(([status,count])({status,count}))这个属于很典型的对象 ↓ entries ↓ 数组 ↓ map转换20.reducereduce是数组方法里稍微难一点的。但你一旦理解以后它特别适合求和 统计 分组 转换数据结构先从最简单的开始。假设constnums[10,20,30]求和consttotalnums.reduce((sum,item){returnsumitem},0)console.log(total)结果6020.1 reduce 到底在干什么这里reduce((sum,item){returnsumitem},0)有三个关键东西sum 累计结果 item 当前元素 0 初始值执行过程大概是初始 sum 0 第1次 item 10 sum 0 10 得到 10 第2次 item 20 sum 10 20 得到 30 第3次 item 30 sum 30 30 得到 60最后返回60所以reduce最核心的思想就是一边遍历一边把结果累计起来。20.2 实战计算总金额比如维修项目constitems[{name:换屏,price:500,quantity:1},{name:换电池,price:200,quantity:2}]总金额consttotalAmountitems.reduce((total,item){returntotalitem.price*item.quantity},0)console.log(totalAmount)结果900因为500 × 1 500 200 × 2 400 总计 900这个就是reduce最典型的业务用途之一。20.3 可以简写consttotalAmountitems.reduce((total,item)totalitem.price*item.quantity,0)以后看到list.reduce((sum,item)sumitem.xxx,0)你直接理解对 xxx 求和。例如consttotalQtyparts.reduce((sum,item)sumitem.quantity,0)就是所有备件数量合计。20.4 实战统计数量例如constorders[{id:1,status:WAIT_REPAIR},{id:2,status:COMPLETED},{id:3,status:WAIT_REPAIR},{id:4,status:REPAIRING},{id:5,status:COMPLETED}]想统计WAIT_REPAIR 2 COMPLETED 2 REPAIRING 1可以conststatusCountorders.reduce((result,item){if(!result[item.status]){result[item.status]0}result[item.status]returnresult},{})结果{WAIT_REPAIR:2,COMPLETED:2,REPAIRING:1}这里为什么初始值是{}刚才求和reduce(...,0)因为最后想得到一个数字。现在reduce(...,{})因为最后想得到一个对象。所以reduce的初始值不是固定的。它取决于你最后想得到什么。例如最后想得到数字 ↓ 0 最后想得到数组 ↓ [] 最后想得到对象 ↓ {}这个理解很关键。20.5 实战按状态分组还是constorders[{id:1,status:WAIT_REPAIR},{id:2,status:COMPLETED},{id:3,status:WAIT_REPAIR}]希望得到{WAIT_REPAIR:[{id:1,status:WAIT_REPAIR},{id:3,status:WAIT_REPAIR}],COMPLETED:[{id:2,status:COMPLETED}]}可以constgroupedorders.reduce((result,item){if(!result[item.status]){result[item.status][]}result[item.status].push(item)returnresult},{})这个就是按字段分组。20.6 Java Stream 类比如果你是 Java 开发这样理解最方便。Javalist.stream().map(User::getName).toList();JSlist.map(itemitem.name)Javalist.stream().filter(User::isEnabled).toList();JSlist.filter(itemitem.enabled)Javalist.stream().mapToInt(Order::getAmount).sum();JSlist.reduce((sum,item)sumitem.amount,0)JavaCollectors.groupingBy(Order::getStatus)JSlist.reduce((result,item){if(!result[item.status]){result[item.status][]}result[item.status].push(item)returnresult},{})所以你完全可以把reduce理解成Java Stream 里很多“最终汇总操作”的通用版本。20.7 reduce 不要滥用虽然reduce很强但不是什么都要 reduce。比如constnamesusers.map(itemitem.name)很清楚。没必要硬写成constnamesusers.reduce((result,item){result.push(item.name)returnresult},[])虽然能做到但是map更符合语义。所以建议转换 → map 筛选 → filter 找一条 → find 求和/汇总/分组 → reduce21. 短路运算和||这两个本身不是 ES6 才出现的但现代 JS 业务代码特别常见所以一定要会。21.1先看truehello结果hello而falsehello结果false所以实际代码经常写isAdminshowAdminPanel()意思如果 isAdmin 为真 ↓ 才执行 showAdminPanel()大致等价if(isAdmin){showAdminPanel()}Vue/JS 实战例如userconsole.log(user.name)意思user 存在才执行后面。不过现在很多场景更推荐user?.name可选链会更直观。21.2||||常用于默认值constnameuserName||未知用户如果userName是假值就使用未知用户例如constpageSizeparams.pageSize||1021.3||的坑前面我们讲??的时候已经碰过。例如constquantity0如果constresultquantity||10结果10因为0属于假值。但如果业务里0 是合法数据那么就不能随便用||。应该constresultquantity??1021.4 JavaScript 常见假值这些都属于 falsyfalse0nullundefinedNaN所以value||defaultValue会把这些都当成“没有值”。而value??defaultValue只把nullundefined当成“没有值”。21.5和||连着写例如consttextuseruser.name||未知用户以前这种写法很常见。意思user存在 ↓ 取user.name 否则 ↓ 未知用户现在通常可以写得更清晰consttextuser?.name??未知用户我更推荐后者。21.6 实战判断比如constorder{status:COMPLETED,paid:true}可以order.paidconsole.log(已支付)不过业务逻辑复杂的时候建议还是正常写if(order.paid){console.log(已支付)}因为短路写法适合简单逻辑不适合塞很长的业务代码。比如这种我就不推荐order.paidorder.statusCOMPLETEDthis.$message.success(工单完成)this.getList()看起来很炫但可维护性差。直接if(order.paidorder.statusCOMPLETED){this.$message.success(工单完成)this.getList()}更清楚。1921 总结你可以这样记19. Object.keys / values / entries ↓ 遍历对象 keys → 属性名 values → 属性值 entries → key value 20. reduce ↓ 累计、统计、汇总、分组 求和 统计数量 按状态分组 21. / || ↓ 短路逻辑 → 前面为真才继续 || → 前面是假值就用后面其中这一组我建议你重点掌握Object.entries(obj)list.reduce((sum,item)sumitem.amount,0)constvaluedata?.value??0尤其是reduce你以后做库存数量、金额汇总、状态统计、按字段分组时非常实用。