其实你可以少写点if else与switch(推荐)


Posted in Javascript onJanuary 10, 2019

前言

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

不过他强任他强,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也是可以到达目的,不过自己思考过之后再去看大神的作品理解会更深入一点。

Javascript 相关文章推荐
JavaScript DOM 学习第五章 表单简介
Feb 19 Javascript
JQuery1.4+ Ajax IE8 内存泄漏问题
Oct 15 Javascript
jquery实现非叠加式的搜索框提示效果
Jan 07 Javascript
鼠标悬浮停留三秒后自动显示大图js代码
Sep 09 Javascript
$(&quot;&quot;).click与onclick的区别示例介绍
Sep 25 Javascript
原生态js,鼠标按下后,经过了那些单元格的简单实例
Aug 11 Javascript
基于iScroll实现下拉刷新和上滑加载效果
Jul 18 Javascript
AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断后添加表格信息)
Oct 24 Javascript
jQuery EasyUI window窗口使用实例代码
Dec 25 jQuery
jQuery ajax仿Google自动提示SearchSuggess功能示例
Mar 28 jQuery
js表达式与运算符简单操作示例
Feb 15 Javascript
深入了解Vue.js 混入(mixins)
Jul 23 Javascript
微信小程序提取公用函数到util.js及使用方法示例
Jan 10 #Javascript
浅谈JavaScript 代码简洁之道
Jan 09 #Javascript
react组件从搭建脚手架到在npm发布的步骤实现
Jan 09 #Javascript
微信小程序公用参数与公用方法用法示例
Jan 09 #Javascript
微信小程序实现的日期午别医生排班表功能示例
Jan 09 #Javascript
Windows下Node爬虫神器Puppeteer安装记
Jan 09 #Javascript
jQuery简单实现根据日期计算星期几的方法
Jan 09 #jQuery
You might like
php实现CSV文件导入和导出
2015/10/24 PHP
基于PHPexecl类生成复杂的报表表头示例
2016/10/14 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
2016/12/19 PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
2019/10/15 PHP
js时间戳格式化成日期格式的多种方法
2013/11/11 Javascript
jquery实现不同大小浏览器使用不同的css样式表的方法
2014/04/02 Javascript
node.js中的fs.lchownSync方法使用说明
2014/12/16 Javascript
vue一步步实现alert功能
2017/07/05 Javascript
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
JavaScript面试出现频繁的一些易错点整理
2018/03/29 Javascript
详解angular如何调用HTML字符串的方法
2018/06/30 Javascript
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
React Component存在的几种形式详解
2018/11/06 Javascript
js实现点击图片在屏幕中间弹出放大效果
2019/09/11 Javascript
ES6使用新特性Proxy实现的数据绑定功能实例
2020/05/11 Javascript
朴素贝叶斯算法的python实现方法
2014/11/18 Python
Tensorflow 查看变量的值方法
2018/06/14 Python
Python从单元素字典中获取key和value的实例
2018/12/31 Python
Python numpy中矩阵的基本用法汇总
2019/02/12 Python
pytorch 固定部分参数训练的方法
2019/08/17 Python
Selenium常见异常解析及解决方案示范
2020/04/10 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
UNIX文件类型
2013/08/29 面试题
致1500米运动员广播稿
2014/02/07 职场文书
试用期转正后的自我评价
2014/09/21 职场文书
护士长2014年度工作总结
2014/11/11 职场文书
兵马俑导游词
2015/02/02 职场文书
无锡灵山大佛导游词
2015/02/09 职场文书
2015年度个人思想工作总结
2015/04/08 职场文书
客户答谢会致辞
2015/07/30 职场文书
《秦兵马俑》教学反思
2016/02/24 职场文书
python 调用js的四种方式
2021/04/11 Python
Redis实现订单自动过期功能的示例代码
2021/05/08 Redis
Java 中的 Lambda List 转 Map 的多种方法详解
2022/07/07 Java/Android