先上总结:
- 条件少的情况,都可以。
- 条件多的情况,使用
switch或者二维数组代替if..else。使用switch的理由:- 美观上,switch看起来更有条理性;
性能上,条件多时,switch性能优于if...else。具体原因:switch底层在编译时候生成跳表,空间换时间提高条件查询速度;而if...else则是条件挨个匹配判断。
switch与if...else区别:
- switch条件判断只能处理条件为常量的情况,对于if(condition > 0 && condition < 100)这种情况无法处理,只能用if...else
switch底层是跳表,优化了查询速度,而if...else没有用到优化的数据结构存储,故性能肯定比不上switch。在编译阶段,switch会生成跳表,等到程序执行可以快速查找到符合条件的分支;而if...else在程序执行的时候还要一层一层分支的判断。- 条件多时,switch看起来逻辑更清晰
判断条件少的情况:
condition && doSth()
condition ? doSth() : doElse()
判断条件多的情况:
一、如果条件判断可以归纳为键值对,可以用switch或者策略模式。
switch方式:
switch(true)
case condition1:
handler1()
break;
case condition2:
handler2()
break;
case condition3:
handler3()
break;
策略模式:
const handleMap = {
condition1: handler1,
condition2: handler2,
condition3: handler3
}
const handleResult = ()=> {
handlerMap[condition]
}
二、 如果判断条件是按照范围之类复杂的条件,那么可以用责任链模式或者二维数组。
if(0 < point < 60) {
handler1()
} else if(61 < point < 80) {
handler2()
} else if(81 < point < 100) {
handler3()
} else if(point === 100) {
handler3()
}
方法一:责任链模式:
以上的方式是用穷举的方式在配置数据中查找到相对应的处理方法,而责任链模式就是将整个处理的逻辑改写成一条责任传递链,请求在这条链上传递,直到有一个对象处理这个请求。
比如:
class Point1 {
handler(condition) {
if (0 < condition && condition < 60) {
handler1()
} else {
return this.point.handler(condition)
}
}
setPoint(p) {
this.point = p
}
}
class Point2 {
handler(condition) {
if (61 < condition && condition < 80) {
handler2()
} else {
this.point.handler(condition)
}
}
setPoint(p) {
this.point = p
}
}
class Point3 {
handler(condition) {
if (81 < condition && condition < 100) {
handler3()
} else {
this.point.handler(condition)
}
}
setPoint(p) {
this.point = p
}
}
class Point4 {
handler(condition) {
if (condition === 100) {
handler4()
} else {
this.point.handler(condition)
}
}
setPoint(p) {
this.point = p
}
}
const point1 = new Point1()
const point2 = new Point2()
const point3 = new Point3()
const point4 = new Point4()
point1.setPoint(point2)
point2.setPoint(point3)
point3.setPoint(point4)
const point = 99
// 由第一层处理逻辑开始处理
point1.handler(point)
方法二:二维数组:
二维数组相当于手动构造映射关系,优化查询速度。
将条件作为数组的第一项,将子数组的第一个元素-第二个元素写成类似于key-value映射,find方法筛选时可以选出符合条件的子数组。
const pointMap = [
[
// 箭头函数,相当于(point)=> return point > 0 && point < 60,返回boolean方便find查询
(point)=> point > 0 && point < 60,
() => handler1()
],
[
(point)=> point > 61 && point < 80,
() => handler2()
],
[
(point)=> point >= 80 && point < 100,
() => handler3()
],
[
(point)=> point === 100,
() => handler4()
]
]
function getPoint(point) {
// 获取符合条件的子数组
const getPointHandler = pointMap.find(item => item[0](point))
// 子数组存在则运行第二个元素
getPointHandler ? getPointHandler[1]() : console.log('error');
}
// 调用
getPoint(86)