天天看点

if else if else语句格式_你本可以少写些 if-else

前言

我不喜欢业务代码中航天飞机式if/else语句, 它复杂而臃肿, 至少从美感而言, switch就比if/else优雅很多. 如果跨语言比较的话, 私以为ReasonML的模式匹配比起寻常的switch语句又要强上太多. JS中对复杂判断的不同写法, 带来的感觉是很不同的, 这篇文章里, 我将简单介绍几种用于替代if/else的写法. 只有熟悉更多代码思路, 才能开阔我们的思维, 如果不能学习写代码的更多可能性, 也许我们就成了被代码控制住的人.

if/else

我们以一个售后流程为例. 用户购买商品后, 可能会因为错件漏件/质量问题/描述不符等原因联系商家进行售后服务, 其中可能会涉及退款/退货/换货/补发等售后支持服务, 商家对此次售后的服务情况也会影响用户对商家的喜好. 在这样的场景下, 我们假设以下伪代码:

if else if else语句格式_你本可以少写些 if-else

在这个场景下, 每一种售后原因导向的售后支持服务内容是不同的, 比如错件漏件时用户不能选择换货服务. 如此一来, 我们的判断条件也就成了一个[售后原因 * 售后支持服务]的二维列表. 此时再加上根据售后原因以及售后支持服务的不同, 判断条件妥妥地升为三维: [售后原因 * 售后支持服务 * 用户喜好]

显然, 在这种重业务逻辑的地方if/else语句显得力不从心, 主要原因如下:

  1. 判断条件后置. 也就是说, 在} else if (serviceReason === '质量问题') {一句中, 我们通常要在行末才能找到判断条件, 而些内容并没有高亮支持, 所以经常与下一行的普通代码混在一起, 让人眼花缭乱无法辨识.
  2. 代码缩进不清晰, 当判断层数增加, 或是花括号中的内容加长, 那么阅读代码的时候, 寻找if语句对应的结束位置总是给人带来负担.
  3. 奢侈的换行, 当if/else语句中的逻辑很短, 像else { user.love(-5 }这段代码, 占用了3行的位置显得过于奢侈.

三目运算符/短路表达式

在一些简单的表达式中, 可以使用三目运算符或短路表达式去简化判断, 如user.love这个函数的调用就可以抽成单独的一句, 所以下面这种判断完全可以进行简化:

if else if else语句格式_你本可以少写些 if-else

逗号运算符

通过括号和逗号运算符, 我们可以把语句变成表达式去执行. 灵活运用逗号运算符可以使三目或短路支持一些更复杂的情况:

if else if else语句格式_你本可以少写些 if-else

不过上述代码, 在Standard规范中是不被推荐的. ESLint会警告你要求将这行内容转化为if/else写法. 当然, 你也可以修改ESLint规范以关闭警告, 前提是你(及团队成员)喜欢这种写法, 也千万不要为了简化而简化.

switch/case

处理复杂的多分支判断时, 大部分人会选择使用switch作为长if/else的替代品, 你觉得下面这种写法如何呢?

if else if else语句格式_你本可以少写些 if-else

很遗憾, 看来switch语句并没有比if/else要好多少. 只是有一点我要强调, 在上面这个例子中, 所有有关判断的关键字的地方(如switch, case, &&, 这些都属于代码高亮区域), 几乎都存在与每一行开头的前两个语元内. 所以目前为止, 单纯就搜寻判断条件的难度而言, switch是要比if/else好上一些, 尽管这种好处会随着判断分支的增加而逐渐被消磨(这算是一种遗憾吧).

其实还有一个令我觉得遗憾的地方, switch语句不能和短路运算符一并使用, 下面是一种错误的示范:

if else if else语句格式_你本可以少写些 if-else

稍微有些难受, 毕竟使用if判断会增加缩进. 现在让我们来看一种更加简洁的思路.

配置数据与业务逻辑分离

配置数据与业务逻辑分离(下简称配置逻辑分离)没有先决条件, 和三目短路表达式一样, 你随时都可以开始在代码中使用它. 使用配置逻辑分离, 通常需要定义一个用来存放数据配置的对象, 同时要定义一个flag作为配置的键, 配置的值则可以是函数, 数组等任意类型的值. 在执行逻辑的地方, 只需要将判断条件与flag进行比对, 就可以获取到当前判断条件下的业务逻辑方法:

if else if else语句格式_你本可以少写些 if-else

有没有眼前一亮的感觉呢?

在上面的代码片段中, 我们将每一种状态的数据配置和执行业务逻辑的代码进行了一定层度的分离, 使得代码长度短了不少. 通过逗号运算符, 我们可以同时执行业务逻辑函数, 并且返回用户对店家的映像分数.

如果你不想这么激进, 也许下面的代码是一种好的实践:

if else if else语句格式_你本可以少写些 if-else

更加灵活的数据配置

上一节使用了对象进行数据配置, 如果说有那么一点遗憾的地方, 那就是尽管属性的值可以为任意类型, 但是属性本身却只能是字符串类型, 这使得某些场景下我们不能很好的发挥配置逻辑分离的作用. 想象以下场景: 每个月末, 商家会挑选出狂热粉丝(喜爱程度大于等于100)发送留言"感谢你"并赠送10元优惠券, 普通粉丝(分数0-100)发送留言"感谢