前言es6
做为搬砖在第一线的底层工人,业务场景历来是没有作不到只有想不到的复杂。数组
不过他强任他强,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对应起来,进而获取想要的值。
这里一直没有达到我最初的目的,即键里面重复的数组,能够不经过多余操做匹配到,上面无论怎么样都进行了处理,这不是懒人的想要的。
若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:787707172,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。