前言

作为搬砖在第一线的底层工人,业务场景从来是没有做不到只有想不到的复杂。

不过他强任他强,if-else全搞定,搬就完了。但是随着业务迭代或者项目交接,自己在看自己或者别人的if代码的时候,心情就不再表述了,各自深有体会。所以我们一起看看if还能怎么写

最基本if-else

假设有这么个场景,不同情况下打印不同值。

因为涉及到的条件太多,就不提三目运算之类优化了。

if (a == 1) {
console.log('a1')
} else if (a == 2) {
console.log('b2')
} else if (a == 3) {
console.log('c3')
} else if (a == 4) {
console.log('d4')
}
/* n..... */

现在还算能看,因为逻辑简单,如果逻辑复杂,迭代多个版本之后,你还敢动吗。

每动一下就战战兢兢,谁知道哪里会遗漏。

那么换种方式呢

switch-case

这样稍微清晰那么一点,差别好像没什么差别:

switch(a){
case 1:
console.log('a1');
break;
/* 省略。。。 */
case 40:
console.log('a40');
break;
}

分离配置信息与执行动作

object映射

定义一个object作为配置对象来存放不同状态,通过链表查找

const statusMap = {
1:()=>{
console.log('a1')
},
2:()=>{
console.log('b2')
}
/* n.... */
}
// 执行
let a = 1
statusMap[a || 1]()

这样比较清晰,将条件配置与具体执行分离。如果要增加其他状态,只修改配置对象即可。

数组映射

当然在某些状态下可以使用数组,来做这个配置对象。

// 这里就涉及其他优化了,例如将执行函数抽离出来,大家不要关注func的内容就好。
// 它就是个function,内容很复杂
const statusArr = [function(){
console.log(1)
},
function () {
console.log(2)
},]
// 执行
let a = 1
statusArr[a || 1]()

数组的要求更高一点,如果是其他key,例如字符串,那么数组就不能满足需求了

升级版:不同key相同value

这样看起来好一点了,那么需求又有变动了,

前面是每种处理方式都不同,下面有几种情况下处理函数相同的,

例如1-39的时候,调用a,40之后调用b,如果我们继续来用映射的方式来处理。

function f1 (){
console.log(1)
}
function f2 (){
console.log(2)
}
const statusMap={
1:f1,
2:f1,
3:f1,
4:f1,
//省略
40:f2
}
let a = 2
statusMap[a]()

这样当然也可以,不过重复写那么多f1,代码看起来不够简洁。

开始重构之前我们先捋一下思路,无非是想把多个key合并起来,对应一个value。

也就是说我们的键值不是字符串而是个数组,object显然只支持字符串,

那么可以将这么多key合并成一个:'1,2,3,4,..,9'。

但是查找的时候有点问题了,我们的参数肯定不能完全匹配。

接着走下去,是不是做个遍历加个判断,包含在子集内的都算匹配,那么代码看起来就是下面这个样子。

// 将键值key设置为一个拼接之后的字符串
const statusMap = {
'1,2,3,4,5': f1,
//省略
40: f2
}
// 获取所有的键值,待会遍历用
const keys = Object.keys(statusMap),
len = keys.length
// 遍历获取对应的值
const getVal=(param='')=>{
// 用for循环的原因在于匹配之后就不需要继续遍历
for (let i = 0; i < len; i++) {
const key = keys[i],
val = statusMap[key]
// 这里用什么来判断就随便了,两个字符串都有。
if (key.includes(param)) {
return val
}
}
}
let a = 2,
handle = getVal(a)
handle() // 1

但是这样来看,增加了个遍历的过程,而且是拼接字符串,万一哪天传了个逗号进来,会得到了预料之外的结果。

map

es6有个新的数据结构Map,支持任意数据结构作为键值。如果用Map可能更清晰一点。

/**
* map键值索引的是引用地址,
* 如果是下面这样的写法不好意思,永远得不到值
* map1.set([1,4,5],'引用地址')
* map1.get([1,4,5]) //输出为undefined
* 就像直接访问
* map1.get([1,2,3,4,5]) //同样为undefined
*/
const map1 = new Map()
const statusArr = [1,2,3,4,5]
map1.set(statusArr,f1)
// 预设默认值,因为不能直接遍历
let handle = function(){}
const getVal = (param = '') => {
for (let value of map1.entries()) {
console.log(JSON.stringify(value))
if (value[0].includes(param)){
console.log(value)
// 不能跳出 只能处理了
handle = value[1]
}
}
}
const a = 2
getVal(a)
handle()

个人而言虽然这样减少了重复代码,但是又增加了一步匹配值的操作,优劣就见仁见智吧。

双数组

肯定有部分人就是不想做遍历的操作,既然一个数组不能满足,那么两个数组呢。

// 键值数组和value 保持对应关系
const keyArr = ['1,2,3,4,5','40']
const valArr = [f1,f2]
const getVal = (param = '')=>{
// 查找参数对应的下标
let index = keyArr.findIndex((it)=>{
return it.includes(param)
})
// 获取对应值
return valArr[index]
}
let a = 2,
handle = getVal(a)
handle()

利用数组提供的下标,将key和value对应起来,进而获取想要的值。

这里一直没有达到我最初的目的,即键里面重复的数组,可以不通过多余操作匹配到,上面不管怎么样都进行了处理,这不是懒人的想要的。

总结

这是在写业务需求的时候做的一点总结,数组和对象的映射可能大家都在用。当遇到了不同key相同value的情况时,从懒出发不像重复罗列,就尝试了下。当然了,因为个人水平问题,肯定有更好的处理方式,欢迎一起讨论,抛砖引玉共同进步。此外现有成熟的库里loadsh也是可以到达目的,不过自己思考过之后再去看大神的作品理解会更深入一点。更多文章请转我的博客

其实我们可以少写点if else和switch的更多相关文章

  1. 搞了我一下午竟然是web.config少写了一个点

    Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...

  2. 【svn】一个设置,少写几个字

    以下场景仅适用于修改bug的时候,在提交代码的时候少写几个字,嘿嘿: 1.打开[SVN 属性],在代码目录右键 2.打开BUG跟踪设置窗口 3.输入BUG的URL前缀以及%BUGID%,如 复选框,建 ...

  3. CI(codeigniter)框架,routes.php设置正确,但是显示服务器错误,是__construct少写了一个下划线

    今天弄了一下CI框架,大概看了一下文档,感觉CI框架非常精简,但是在做的时候遇到了问题,CI文档中提供了一个新闻系统的例子,所有工作都做完了,在浏览器中打开相对应的url是,却显示“服务器错误”,一点 ...

  4. CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅

    首页   登录注册         CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅 阅读 8113 收藏 927 2017-09-26 原文链接:github.com 腾讯云容器服务CSS,立 ...

  5. this.$Message.success('提示信息') 少写了一个c 导致报错

    this.$Message.success('提示信息') 少写了一个c 导致报错 而且 $Message 输出还没显示,导致我以为是没有 $Message 对象了,其实全局对象直接调用即可

  6. Python 2.7 因为少写括号导致的 SyntaxError 错误

    贴代码: # -*- coding: utf-8 -*- # 控制缩进tab数量 def GetTabStr(tab_num): tab_str = "" for i in xra ...

  7. 国产CPU走到十字路口:谁来取代英特尔芯片?(少写了一个OpenPower)

    国内的几支CPU研发力量各自选择的指令体系都有自己的优点和问题,选择其中的哪一支都会有对应的成本和风险.最终谁能担大任,且拭目以待. 文 | 瞭望智库特约科技观察员 王强 用上内置国产CPU的个人电脑 ...

  8. 爬数据,能让你少写1000行代码的捷径! | Python 正则表达式

    ▌春暖花开,又到了出门游玩拍拍拍吃吃吃的好季节了! 说到拍照摄影,你会构图吗?就是在照片有限的空间内处理人.景.物的关系,并将三者安排在画面中最佳的位置,以形成画面特定结构的方法. 学院君就是一个「拍 ...

  9. C++STL 中的容器整体/逐元素操作方法 少写80%for循环

    本文中示例代码默认已引用 std 命名空间 累加 (std::accumulate) accumulate(begin, end, init, op) 返回给定区间内元素的累加值与给定初值的和,初值不 ...

随机推荐

  1. 电子书转换为PDF格式

    目录 一.mobi 转换 pdf 步骤 二.查看转换后的结果目录 三.将PDF还原文件名且移出至新目录 背景:当我们从网上下载一些电子小说或书籍的时候,一般文件的格式可能是.epub..mobi等.这 ...

  2. js变量前的+是什么意思

    js变量前的+是什么意思   if (+value >= distance) {} 这个+什么意思 可以理解为 Number(value) 会将其按照Number函数的规则转换为数值或者NaN, ...

  3. Allegro PCB Design GXL (legacy) 刷新PCB封装(Package)中的焊盘(Padstack)

    Allegro PCB Design GXL (legacy) version 16.6-2015 “人有失足,马有失蹄”. 像这个电位器的封装的Pin 6,在制作Padstack时,因没有添加SOL ...

  4. 阿里云人脸识别测试接口出错 返回Body:{ "errno": 1031, "err_msg": "Invalid Image URL.", "request_id": "cdbe2927-e1bb-4eb1-a603-8fcd4b0b7fc8" }

    错误信息如下 返回Body:{ "errno": 1031, "err_msg": "Invalid Image URL.", " ...

  5. 在th中显示图片

    从DataTable中获取值: foreach (DataRow dr in ((DataTable)ViewBag.bookInfoList).Rows) { <tr> <th c ...

  6. photoshop CC智能切图

    网页设计在技术层面上,第一步是美工做出网页效果图,第二步就是网页前端进行网页切图.网页切图工具常用的有fireworks.PS,这里使用PS进行网页切图. 我们通过设计稿,得到我们想要的产出物(如.p ...

  7. LeetCode高频148错题记录

    3. Max Points on a Line 共线点个数3种解法 思路一:思考如何确定一条直线,两点法,确定斜率后带入一点.有三种情况,1. 两点重合,2. 斜率不存在,3. 正常算,依次以每个点为 ...

  8. GGTalk ——C#开源即时通讯系统

    http://www.cnblogs.com/justnow/ GGTalk ——C#开源即时通讯系统 下载中心   GGTalk(简称GG)是可在广域网部署运行的QQ高仿版,2013.8.7发布GG ...

  9. ionic2/cordova自定义插件集成aar包

    一.准备自定义插件 1. 准备:安装plugman npm install -g plugman 2. 新建组件 plugman create --name MyPlugin --plugin_id ...

  10. selenium WebDriver 对浏览器标签页的切换

    关于selenium WebDriver 对浏览器标签页的切换,现在的市面上最新的浏览器,当点击一个链接打开一个新的页面都是在浏览器中打开一个标签页,而selenium只能对窗口进行切换的方法,只能操 ...