避免if语句的深层次嵌套
公司做了个抢红包的限制,然后ajax请求的返回字段,要进行多层逻辑的判断,想想是真恶心,虽然都是简单逻辑,而且看别人以前写的代码,发现,哎,注释能不能写上吶,像我写代码都是细致到,哪怕初学者也能看懂这是要实现什么,还有尽量避免深层次的if嵌套,不然后面产品要加新需求,条件限制了,来个五六个if嵌套,,想想都蛋疼了,故而就查询了一下如何优化,然后把之前的代码给重新整理了下,哎,强迫症又犯了,明明不是自己挖的坑,还是想填了!
那么问题来了,在js开发中,如何减少if else语句的使用
代码中嵌套的if/else结构往往导致代码不美观,也不易于理解。面向过程的开发中代码有大量的IF ELSE,在java中可以用一些设计模式替换掉这些逻辑,那么在js中是否也有类似的方法用来尽可能减少代码中的if/else嵌套呢?
有人认为:if else多就多呗,只要可读性强,维护起来方便。jQuery.fn.init里就是一堆if else判断,难道要质疑jQuery作者的水平了?并不是说if else多就不好,关键是看用的地方,jQuery.fn.init里除了if else判断简洁点,难道要改成switch?就算用工厂模式,还不是得做大量的if判断。
代码整洁强迫症患者必须要来个抛砖引玉:
1.
-
if(a为真){
-
a=a
-
}else{
-
a=b
-
}
-
可写成:a = a || b
2.
-
if(a==b){
-
a=c
-
}else{
-
a=d
-
}
可写成:a = (a==b) ? c : d
3.
后台接口通常会返回这种数据:
fruit: 0 // 0=苹果,1=梨子,2=桔子,3=柠檬,4=芒果...
这时写if...else是最痛苦的。从冲哥那偷来个方法:
-
var _f = ['苹果','梨子','桔子','柠檬','芒果'];
-
shuiguo = _f[fruit];
建议:
第一步:优化if逻辑
人们考虑的东西到时候,都会把最可能发生的情况先做好准备。优化if逻辑的时候也可以这样想:把最可能出现的条件放在前面,把最不可能出现的条件放在后面,这样程序执行时总会按照带啊名的先后顺序逐一检测所有的条件,知道发现匹配的条件才会停止继续检测。
if 的优化目标:最小化找到分支之前所判断条件体的数量。if优化的方法:将最常见的条件放在首位。
-
if (i < 5) {
-
// 执行一些代码
-
} else if (i > 5 && i < 10) {
-
// 执行一些代码
-
} else {
-
// 执行一些代码
-
}
例如上面这个例子,只有在 i 值经常出现小于5的时候是最优化的。如果i值经常大于或者等于10的话,那么在进入正确的分支之前,就必须两次运算条件体,导致表达式的平均运算时间增加。 if 中的条件体应该总是按照从最大概率到最小概率排列,以保证理论速度最快。
第二步:尽量少使用else
如果在函数中,可以使用 if + return ,先判断错误条件,然后立马结束函数,防止进入 else 分支。
举个简单的例子,后端返回数据,前端根据状态进行不同操作
-
$.ajax().done(function (res) {
-
if (res.state === 'SUCCESS') {
-
//TODO
-
} else if (res.state === 'FAIL') {
-
//TODO
-
} else {
-
//TODO
-
}
-
});
-
这里用if else不挺好的么,有啥问题么?不过我个人倾向于switch。
解决方法:
1. switch/case
switch和if else在性能上是没有什么区别的,主要还是根据需求进行分析和选择。
如果条件较小的话选用if else比较合适。
相反,条件数量较大的话,就建议选用switch。
一般来说,if else适用于两个离散的值或者不同的值域。如果判断多个离散值,使用switch更加合适。
在大多数的情况下switch比if else运行的更加快。
在大多数情况下,switch的性能不会比if else低。switch的确在实质上跟if else if 完全一样的效果,不过在很多情况下,使用switch要比if else方便不少
比如经典的值等分支,匹配一些状态常量的时候,比if else结构方便许多,不用反复写xx == yy
-
$.ajax().done(function (res) {
-
switch (res.state) {
-
case 'SUCCESS':
-
//TODO
-
break;
-
case 'FAIL':
-
//TODO
-
break;
-
default :
-
//TODO
-
}
-
});
-
注意:千万不要忘记在每一个case语句后面放一个break语句。也可以放一个return或者throw。case语句匹配expression是用===而不是==。
2.hash 表
-
if (key == "Apple") {
-
val = "Jobs";
-
} else if (key == "microsoft"){
-
val = "Gates";
-
} else if (key == "Google"){
-
val = "Larry";
-
}
这个也可以用 switch case 解决,不过推荐的方法是 hash 表:
-
var ceos = {"Apple":"Jobs", "microsoft":"Gates", "Google":"Larry"};
-
val = ceos[key];
3.重构,用 OO 里面的继承或者组合
-
1.如果是狗,则汪汪
-
2.如果是猫,则喵喵
-
3.如果是羊,则咩咩
-
4.如果是鸭,则嘎嘎
可以重构一下,改成 OO。
-
*定义类: 动物(或者接口)
-
*定义方法:叫
-
*定义子类:狗、猫、羊、鸭
-
*重写方法 ---- 叫
也就是说将同的判断按照功能,写成函数,这样也便于阅读
比如我有一个方法根据类型获取名称,用if else会这样
-
function getName(type) {
-
if (type === 'monkey') {
-
return 'monkey name';
-
} else if (type === 'cat') {
-
return 'cat name';
-
} else {
-
return 'dog name';
-
}
-
}
如果写成函数,改成下面的会更好
-
function getName(type) {
-
var data = {
-
monkey: 'monkey name',
-
cat: 'cat name',
-
dog: 'dog name'
-
}
-
-
return data[type] ? data[type] : data['dog'];
-
}
硬要把设计模式添加到JS里不是不可以,但是要看情况。生搬硬套过来的东西然并卵啊。写代码记住三个字即可,短简易。代码短,读起来简单,维护容易,如果在性能和代码长度上二选一,我肯定选代码短,性能不行,加台服务器就是了。而冗长的代码并不是加个程序员就能搞定的。
保持着这个心态写代码,写出的东西离设计模式也不会差太多了。
避免if语句的深层次嵌套的更多相关文章
- html5 webDatabase 存储中sql语句执行可嵌套使用
html5 webDatabase 存储中sql语句执行可嵌套使用,代码如下: *); data.transaction(function(tx){ tx.executeSql("creat ...
- T-SQL查询语句(二):嵌套查询
一个select...From...Where查询语句块可以嵌套在另一个select...From...Where查询块的Where子句中,称为嵌套查询.外层查询称为父查询,主查询.内层查询称为子查询 ...
- 分支语句 if的嵌套 循环语句
0930 今天学习内容做以下总结: 语句的分类:顺序语句,分支语句(选择,条件),循环语句 分支语句 格式1:if(表达式(要么是true 要么是false)){} 格式2:if(){}slse{} ...
- sql语句中单引号嵌套问题
在sql语句中,我们难免会用到单引号嵌套的时候,但是直接嵌套肯定是不行的,java中用反斜杠做转义符也是不行的,在sql中是用单引号来做转义符的. 比如下面例子是存储过程里查询时的语句示例 exec ...
- 【2017-2-21】C#分支语句,分支嵌套,变量的作用域
分支语句 句式:if else(必须是if开头,可以是else if或者else结束,也可以直接结束) if(bool型比较表达式) { 如果上面的条件成立,则执行这里面的代码 } else if(b ...
- c#循环语句 for 循环嵌套的练习。还有跳转语句,异常语句,迭代穷举介绍
先说一下循环嵌套:循环嵌套就是再一个循环里面再放一个循环,也就是说如果没一个循环都循环10次,那么第一个循环是1的时候,嵌套的循环会循环十次.也就是10*10的效果. for 循环语句 主要还是逻辑思 ...
- 判断语句、if嵌套
判断语句 上一篇我们使用了一下if语句当然我们不止这些 我们上一个只是判断出如果满足条件会执行,那么我们想一想如果不能满足该会怎么样! 当然 还有一种语句叫做if else 他的语法格式是: if ( ...
- c#语句 for循环嵌套
1.打印三角形. 1) 方法一.for嵌套 方法二.只用一个for 2)倒三角 3)后三角 2.求100以内质数的和. 3.一张纸厚度为0.01米,至少对折多少次才能达到珠峰的高度?(用for死循环) ...
- C# 循环语句 for循环(嵌套 while 穷举 迭代)
for循环的嵌套类似于if else 事例: 打印矩阵,外循环对应行,内循环对应列 for (int k = 1; k <= 5; k++) { for (int i = 1; i <= ...
随机推荐
- 获取input file 选中的图片,并在一个div的img里面赋值src实现预览
代码如下利用html5实现:几乎兼容所有主流浏览器,当然IE必须是IE 6以上 [jquery代码] $(function() { $("#file_upload").change ...
- 开发板 Linux驱动视频 驱动是什么
内存管理单元很重要. linux把设备看成文件,(open,read,write,ioctrl,close)主要写这几个函数. 哈弗结构,取指令和取数据同时进行. arm处理器体系架构以及发展方向 单 ...
- HDU 4508 湫湫系列故事——减肥记I (2013腾讯编程马拉松初赛第一场)
http://acm.hdu.edu.cn/showproblem.php?pid=4508 题目大意: 给定一些数据. 每组数据以一个整数n开始,表示每天的食物清单有n种食物. 接下来n行,每行两 ...
- EventWaitHandle
在查资料的过程中,我突然想到一个类:EventWaitHandle,也就是本文的主角. 这个类通过在线程之间设置信号量,可以非常方便的控制线程运行的顺序.具体代码如下: 首先全局申明: EventWa ...
- 把java程序打包成.exe
准备工作:将可执行的jar包跟资源跟第三方包都放到一个目录下. 能够将jre包也放入里面.这样在没有安装jre的情况下也能够执行. watermark/2/text/aHR0cDovL2Jsb2cuY ...
- JSP语法基础(一)
一.JSP页面中的凝视 (1)HTML凝视 <!-- comment [ <%=expression %> ] --> 能在client显示的一种凝视,标记内的全部JSP脚本元 ...
- JS实现跑马灯效果(鼠标滑入可暂停,离开继续跑)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Redis实现Mybatis的二级缓存
一.Mybatis的缓存 通大多数ORM层框架一样,Mybatis自然也提供了对一级缓存和二级缓存的支持.一下是一级缓存和二级缓存的作用于和定义. 1.一级缓存是SqlSession级别的缓存.在操作 ...
- 打开utf-8文件乱码的解决方法
gvim一直用的好好的,但是今天看一网友贴出来的代码时,却发现中文显示乱码了.... 使用notepad++打开,右下角显示是utf-8 w/0 BOM. 马上放狗, 发现解决方法如下: 在_vi ...
- 在云服务器上(CentOS)上安装Node
今天手抖,买了台云服务器,本人对服务器啥的基本不懂,linux命令基本靠度娘,所以连装个node环境都历经坎坷,搞了一下午终于搞好了,记录一下: 第一步:当然是先登录服务器了,打开命令行窗口,输入: ...