if-else 的优美写法
前言♂️
相信大家或多或少都接触过拥有庞大 if else 的项目代码吧,多重嵌套的 if else 在维护的时候真的让人很恼火,有时候一个 bug 排查下来,严重感觉身体被掏空。
本文并未有消灭或歧视 if else的意思,if else 的好用都知道,这里只是在某些特定场景为大家额外提供一种思路,增加我们代码的可读性。
短路运算
Javascript 的逻辑或 || 的短路运算有时候可以用来代替一些比较简单的 if else
- 逻辑或
||的短路运算:若左边能转成true,返回左边式子的值,反之返回右边式子的值。
下面用一个简单的案例来表述
let c
if(a){
c = a
} else {
c = b
}
大家看着上面的代码会难受嘛(本人有一丢丢的强迫症),明明就是一个很简单的判断却需要写好几行代码才能实现。这个时候我们就可以用短路运算去简化我们的代码啦。
let c = a || b
这样看起来是不是就简洁了很多。
三元运算符
三元运算符我觉得大家应该都很熟悉吧,很多时候简单的一些判断我们都可以使用三元运算符去替代 if else,这里只推荐 一层 三元运算符,因为多层嵌套的三元运算符也不具备良好的可读性。
例子:条件为 true 时返回1,反之返回0:
const fn = (nBoolean) {
if (nBoolean) {
return 1
} else {
return 0
}
}
// 使用三元运算符
const fn = (nBoolean) {
return nBoolean ? 1 : 0
}
三元运算符使用的地方也比较多,比如:条件赋值,递归...
// num值在nBoolean为true时为10,否则为5
let num = nBoolean ? 10 : 5
// 求0-n之间的整数的和
let sum = 0;
function add(n){
sum += n
return n >= 2 ? add(n - 1) : result;
};
let num = add(10);//55
switch case️
上述的两种方式:短路运算跟三元运算虽然很好用,代码也很简洁,不过都只能用于简单的判断,遇到多重条件判断就不能使用了。
对于 switch case,虽然它的可读性确实比 else if 更高,但是我想大家应该都觉得它写起来比较麻烦吧(反正我觉得很麻烦)。
例:有A、B、C、D四种种类型,在A、B的时候输出1,C输出2、D输出3,默认输出0。
let type = 'A'
//if else if
if (type === 'A' || type === 'B') {
console.log(1);
} else if (type === 'C') {
console.log(2);
} else if(type === 'D') {
console.log(3);
} else {
console.log(0)
}
//switch case
switch (type) {
case 'A':
case 'B':
console.log(1)
break
case 'C':
console.log(2)
break
case 'D':
console.log(3);
break;
default:
console.log(0)
}
对象配置/策略模式
对象配置看起来跟 策略模式 差不多,都是根据不同得参数使用不同得数据/算法/函数。
策略模式就是将一系列算法封装起来,并使它们相互之间可以替换。被封装起来的算法具有独立性,外部不可改变其特性。
接下来我们用对象配置的方法实现一下上述的例子
let type = 'A'
let tactics = {
'A': 1,
'B': 1,
'C': 2,
'D': 3,
default: 0
}
console.log(tactics[type]) // 1
接下来用几个例子让大家更加熟悉一点。
案例1 商场促销价
根据不同的用户使用不同的折扣,如:普通用户不打折,普通会员用户9折,年费会员8.5折,超级会员8折。
使用if else实现
// 获取折扣 --- 使用if else
const getDiscount = (userKey) => {
if (userKey === '普通会员') {
return 0.9
} else if (userKey === '年费会员') {
return 0.85
} else if (userKey === '超级会员') {
return 0.8
} else {
return 1
}
}
console.log(getDiscount('普通会员')) // 0.9
使用对象配置/策略模式实现
// 获取折扣 -- 使用对象配置/策略模式
const getDiscount = (userKey) => {
// 我们可以根据用户类型来生成我们的折扣对象
let discounts = {
'普通会员': 0.9,
'年费会员': 0.85,
'超级会员': 0.8,
'default': 1
}
return discounts[userKey] || discounts['default']
}
console.log(getDiscount('普通会员')) // 0.9
从上面的案列中可以明显看得出来,使用对象配置比使用if else可读性更高,后续如果需要添加用户折扣也只需要修改折扣对象就行。
对象配置不一定非要使用对象去管理我们键值对,还可以使用 Map去管理,如:
// 获取折扣 -- 使用对象配置/策略模式
const getDiscount = (userKey) => {
// 我们可以根据用户类型来生成我们的折扣对象
let discounts = new Map([
['普通会员', 0.9],
['年费会员', 0.85],
['超级会员', 0.8],
['default', 1]
])
return discounts.get(userKey) || discounts.get('default')
}
console.log(getDiscount('普通会员')) // 0.9
案例2 年终奖
公司的年终奖根据员工的工资基数和绩效等级来发放的。例如,绩效为A的人年终奖有4倍工资,绩效为B的有3倍,绩效为C的只有2倍。
假如财务部要求我们提供一段代码来实现这个核算逻辑,我们要怎么实现呢?
这不是很简单嘛,一个函数就搞定了。
const calculateBonus = (performanceLevel, salary) => {
if (performanceLevel === 'A'){
return salary * 4
}
if (performanceLevel === 'B'){
return salary * 3
}
if (performanceLevel === 'C'){
return salary * 2
}
}
calculateBonus( 'B', 20000 ) // 输出:60000
可以发现,这段代码十分简单,但是 calculateBonus函数比较庞大,所有的逻辑分支都包含在if else语句中,如果增加了一种新的绩效等级D,或者把A等级的倍数改成5,那我们必须阅读所有代码才能去做修改♂️。
所以我们可以用对象配置/策略模式去简化这个函数
let strategies = new Map([
['A', 4],
['B', 3],
['C', 2]
])
const calculateBonus = (performanceLevel, salary) => {
return strategies.get(performanceLevel) * salary
}
calculateBonus( 'B', 20000 ) // 输出:60000
至此,这个需求做完了,然后产品经理说要加上一个部门区分,假设公司有两个部门D和F,D部门的业绩较好,所以年终奖翻1.2倍,F部门的业绩较差,年终奖打9折。
改造以上代码,把状态值拼接,然后存入Map中
// 以绩效_部门的方式拼接键值存入
let strategies = new Map([
['A_D', 4 * 1.2],
['B_D', 3 * 1.2],
['C_D', 2 * 1.2],
['A_F', 4 * 0.9],
['B_F', 3 * 0.9],
['C_F', 2 * 0.9]
])
const calculateBonus = (performanceLevel, salary, department) => {
return strategies.get(`${performanceLevel}_${department}`) * salary
}
calculateBonus( 'B', 20000, 'D' ) // 输出:72000
结尾
本文主要是向大家传递一种思想,我们有很多的方法去优化我们的代码,提高我们代码的可读性。
对if else并没有歧视的意思,只是希望在大家以后的代码中不仅仅只有if else
if-else 的优美写法的更多相关文章
- react按需加载(getComponent优美写法),并指定输出模块名称解决缓存(getComponent与chunkFilename)
react配合webpack进行按需加载的方法很简单,Route的component改为getComponent,组件用require.ensure的方式获取,并在webpack中配置chunkFil ...
- luogu 3709 大爷的字符串题 构造 莫队 区间众数
题目链接 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符\(x\),然后把\(x\)从这个区间中删除,你要维护一个集合S 如果\(S\)为空,你\(r ...
- js中的if判断十分优美的简洁写法
本尊混迹猿人类也有5年有余,从最开始的C#到java再到php到至今的python,不能说精通,也算得上是熟悉,对各个语言的语法也算是了解. 虽然目前在开发web程序,了解一些java知识,但是今天在 ...
- JavaScript技巧&写法
原文:JavaScript技巧&写法 JavaScript技巧篇: 1>状态机 var state = function () { this.count = 0; this.fun = ...
- 如何写出格式优美的javadoc?
如果你读过Java源码,那你应该已经见到了源码中优美的javadoc.在eclipse 中鼠标指向任何的公有方法都会显示出详细的描述,例如返回值.作用.异常类型等等. 本文主要来自<Thinki ...
- javascript的优美与鸡肋
--总结来自:<javascript语言精粹> 任何语言都有其优美的地方和其鸡肋的地方.避归一些语言的糟粕,能相应的降低bug出现的几率. 优美处: 函数是头等对象 基于原型继承的动态对象 ...
- 基于AOP的MVC拦截异常让代码更优美
与asp.net 打交道很多年,如今天微软的优秀框架越来越多,其中微软在基于mvc的思想架构,也推出了自己的一套asp.net mvc 框架,如果你亲身体验过它,会情不自禁的说‘漂亮’.回过头来,‘漂 ...
- obj.style.z-index的正确写法
obj.style.z-index的正确写法 今天发现obj.style.z-index在js里面报错,后来才知道在js里应该把含"-"的字符写成驼峰式,例如obj.style.z ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- .NET跨平台之旅:数据库连接字符串写法引发的问题
最近在一个ASP.NET Core站点中遇到一个奇怪问题.当用dotnet run命令启动站点后,开始的一段时间请求执行速度超慢,有时要超过20秒,有时甚至超过1分钟,日志中会记录这样的错误: Sys ...
随机推荐
- jmeter录制登录脚本
1.添加代理服务器 在非测试元件添加http代理服务器,端口写8888,域写127.0.0.1 在排除模式里填入.*.(js|css|PNG|jpg|ico|png|gif|woff|ttf).* 2 ...
- [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT
题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...
- 使用 Spring Security 手动验证用户
1.概述 在这篇快速文章中,我们将重点介绍如何在 Spring Security 和 Spring MVC 中手动验证用户的身份. 2.Spring Security 简单地说,Spring Secu ...
- Azure DevOps Pipelines部署.Net Core 应用到Kubernetes
一. 先决条件 1.Azure Repos Git/Git和项目上传 把本地的Net Core项目上传至Azure Repos Git/Git 2.Docker Registry Service ...
- JSP中实现留言页面的编写并将留言信息展示出来
1.JavaBean类,实现java代码和html的部分分离,提高代码的复用 package com.wgh; public class MessageBean { private String au ...
- springboot+mybatis+shiro项目中使用shiro实现登录用户的权限验证。权限表、角色表、用户表。从不同的表中收集用户的权限、
要实现的目的:根据登录用户.查询出当前用户具有的所有权限.然后登录系统后.根据查询到的权限信息进行不同的操作. 以下的代码是在搭好的框架之下进行的编码. 文章目录 核心实现部分. 第一种是将用户表和角 ...
- NLP之基于Seq2Seq和注意力机制的句子翻译
Seq2Seq(Attention) @ 目录 Seq2Seq(Attention) 1.理论 1.1 机器翻译 1.1.1 模型输出结果处理 1.1.2 BLEU得分 1.2 注意力模型 1.2.1 ...
- GIT入门与Gitee的使用
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 工作原理 / 流程: Workspace:工作区Index / Stage:暂存区Repository:仓库区(或本地仓库)Remo ...
- Pthread 并发编程(一)——深入剖析线程基本元素和状态
Pthread 并发编程(一)--深入剖析线程基本元素和状态 前言 在本篇文章当中讲主要给大家介绍 pthread 并发编程当中关于线程的基础概念,并且深入剖析进程的相关属性和设置,以及线程在内存当中 ...
- Linux---ls cd
ls 命令 ls命令是linux下最常用的命令,是 list 的缩写,可以用各种方式查看目录中的内容. 格式: ls [选项] [目录名] 常用参数 short long function -a -- ...