有一再有二,有二再有三。把未知的变成已知,就成了自己的知识
前言
很久之前,发了一篇文章:
[浅析]特定场景下取代if-else和switch的方案
,但是关于使用 if-else 的场景可不会仅仅是上面文章那么少,还有很多的场景,今天再次写下在开发上有哪些可以代替或者优化
if-else
的场景。
这里强调代替或者优化
if-else
,是在特定场景下进行的。目的就是为了在特定场景下改善代码,让代码简洁。增加代码的可读性,维护性,复用性。如果if-else
使用的场景比较简单,或者代替,优化if-else
后会对代码产生不好的影响。就不建议使用别的方案代替或者优化,不能为了不写if-else
而不写,不能为了优化而优化。
1.范围查询
比如抽取中奖的号码区间,中奖的号码区间分别是 9-12,14-18,然后需要判断号码是否中奖了,逻辑很简单就实现了
let num1= 15
let num2= 13
if((num1>=9 && num1<=12)||(num1>=14 && num1<=18)){
// 中奖了
}
if((num2>=9 && num2<=12)||(num2>=14 && num2<=18)){
// 中奖了
}
复制代码
这样写貌似没什么问题,如果以后需求变了,中奖的号码不是9-12或者14-18。而是 10-14 或者 18-20。这样就要改原来的代码逻辑
if((num1>=10 && num1<=14)||(num1>=18 && num1<=20)){
// 中奖了
}
复制代码
或者又有其他需求,比如中奖号码是 9-12,14-18,20-22或者26-30。还是要改动一下 if-else 的逻辑
if((num1>=9 && num1<=12)||(num1>=14 && num<=18)||(num1>=20 && num1<=22)||(num2>=26 && num1<=30)){
// 数字在范围内
}
复制代码
现在可以用some 进行封装一个函数,只需要一次封装,往后的需求如果范围区间改变了,就可以
function handleCheckRange(num, ...ranges){
return ranges.some(item=>num>=item[0]&&num<=item[1])
}
handleCheckRange(num1,[9,12],[14,18]) //true
handleCheckRange(num2,[9,12],[14,18]) //false
handleCheckRange(num2,[10,14],[18,20]) //true
handleCheckRange(num2,[9,12],[14,18],[20,22],[26,30]) //false
复制代码
1.可能有人会想到如果再有需求,判断条件不是 >= 或者 <= 。可能是 < 和 >,<= 和 >,或者 < 和 >=呢?这样
handleCheckRange
也是需要改了。这种情况确实,遇到其他的判断条件是需要改一下这个方法。但是改一下这个方法并不难,直接封装就好2.如果判断条件太多变化,一定要封装方法兼容其他的判断条件,可以参考我的笔记: 练习题5:模拟实现开闭区间 ,这里就不展开讲了。
2.多个与条件
相信大家都会遇到可能会有多个条件组合的问题
比如有一个参与热卖活动赠积分活动,活动状态(
status
),预热中(
status=1
),进行中(
status=2
)。用户类型(
type
)也有分普通用户(
type=1
)vip用户(
type=2
)
规则是: 1.在预热中参与活动,vip用户赠送 1000 积分,普通用户赠送 700 积分。 1.在进行中参与活动,vip用户赠送 800 积分,普通用户赠送 300 积分。
之前写法是
let status=1
let type=2
if(status===1){
if(type===1){
console.log('普通用户在预售中参与活动,赠送700积分')
}
else if(type===2){
console.log('vip用户在预售中参与活动,赠送1000积分')
}
}
else if(status===2){
if(type===1){
console.log('普通用户在进行中参与活动,赠送300积分')
}
else if(type===2){
console.log('vip用户在进行中参与活动,赠送800积分')
}
}
// 或者
if(status===1&&type===1){
console.log('普通用户在预售中参与活动,赠送700积分')
}
else if(status===1&&type===2){
console.log('vip用户在预售中参与活动,赠送1000积分')
}
else if(status===2&&type===1){
console.log('普通用户在进行中参与活动,赠送300积分')
}
else if(status===2&&type===2){
console.log('vip用户在进行中参与活动,赠送800积分')
}
复制代码
但是现在可以使用 obj写法,这样下来,如果以后有什么条件改了,直接改 obj 这个配置就好。
let obj={
'status=1&type=1':'普通用户在预售中参与活动,赠送700积分',
'status=1&type=2':'vip用户在预售中参与活动,赠送1000积分',
'status=2&type=1':'普通用户在进行中参与活动,赠送300积分',
'status=2&type=2':'普通用户在进行中参与活动,赠送800积分'
}
console.log(obj[`status=${status}&type=${type}`])
复制代码
3.多个或条件
比如输入一个城市名字,输出一个省份名称
let city='广州'
if(city==='广州'||city==='佛山'){
console.log('广东')
}
else if(city==='海口'||city==='三亚'){
console.log('海南')
}
复制代码
这样写的弊端就是,如果
if-else
数量一多,代码就会多,而且判断的条件会变得很长,还有一个问题就是风格有可能不会统一
下面用其他方法进行优化下 方法一
let arr=[
{
city:'广州',
province:'广东'
},
{
city:'佛山',
province:'广东'
},
{
city:'海口',
province:'海南'
},
{
city:'三亚',
province:'海南'
}
]
console.log(arr.filter(item=>item.city===city)[0].province)//广东
复制代码
方法二
let city='广州'
let obj={
'广州':'广东',
'佛山':'广东',
'海口':'海南',
'三亚':'海南',
}
console.log(obj[city])// 广东
复制代码
见到 广东 和 海南 写了这么多次,可能大家都会郁闷,一个省城市有 20 个,就要写 20 次,可能就有人会想到把城市都作为
key
,然后判断传进来的
city
是否在
key
里面,代码如下。
let city='广州'
let obj={
'广州,佛山':'广东',
'海口,三亚':'海南',
}
for(let key in obj){
if(key.includes(city)){
console.log(obj[key])
break
}
}
//广东
复制代码
但是弊端也出来了,就是上面的方法有
bug
,只输出城市名称的其中一个字,也能输出对应的省份。
let city='州'
let obj={
'广州,佛山':'广东',
'海口,三亚':'海南',
}
for(let key in obj){
if(key.includes(city)){
console.log(obj[key])
break