前言:

我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得越来越臃肿,越来越看不懂,我借鉴了下美文如下:

举个栗子:

  1. const onButtonClick = (status)=>{
  2. if(status == 1){
  3. sendLog('processing')
  4. jumpTo('IndexPage')
  5. }else if(status == 2){
  6. sendLog('fail')
  7. jumpTo('FailPage')
  8. }else if(status == 3){
  9. sendLog('fail')
  10. jumpTo('FailPage')
  11. }else if(status == 4){
  12. sendLog('success')
  13. jumpTo('SuccessPage')
  14. }else if(status == 5){
  15. sendLog('cancel')
  16. jumpTo('CancelPage')
  17. }else {
  18. sendLog('other')
  19. jumpTo('Index')
  20. }
  21. }

通过代码可以看到这个按钮的点击逻辑:根据不同活动状态做两件事情,发送日志埋点和跳转到对应页面,大家可以很轻易的提出这段代码的改写方案,switch出场:

  1. /**
  2. * 按钮点击事件
  3. * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
  4. */
  5. const onButtonClick = (status)=>{
  6. switch (status){
  7. case 1:
  8. sendLog('processing')
  9. jumpTo('IndexPage')
  10. break
  11. case 2:
  12. case 3:
  13. sendLog('fail')
  14. jumpTo('FailPage')
  15. break
  16. case 4:
  17. sendLog('success')
  18. jumpTo('SuccessPage')
  19. break
  20. case 5:
  21. sendLog('cancel')
  22. jumpTo('CancelPage')
  23. break
  24. default:
  25. sendLog('other')
  26. jumpTo('Index')
  27. break
  28. }
  29. }

  嗯,这样看起来比if/else清晰多了,细心的同学也发现了小技巧,case 2和case 3逻辑一样的时候,可以省去执行语句和break,则case 2的情况自动执行case 3的逻辑。

还有更简单的写法:

 
  1. const actions = {
  2. '1': ['processing','IndexPage'],
  3. '2': ['fail','FailPage'],
  4. '3': ['fail','FailPage'],
  5. '4': ['success','SuccessPage'],
  6. '5': ['cancel','CancelPage'],
  7. 'default': ['other','Index'],
  8. }
  9. /**
  10. * 按钮点击事件
  11. * @param {number} status 活动状态:1开团进行中 2开团失败 3 商品售罄 4 开团成功 5 系统取消
  12. */
  13. const onButtonClick = (status)=>{
  14. let action = actions[status] || actions['default'],
  15. logName = action[0],
  16. pageName = action[1]
  17. sendLog(logName)
  18. jumpTo(pageName)
  19. }

这种方法的聪明之处在于:将判断条件作为对象的属性名,将处理逻辑作为对象的属性值,在按钮点击的时候,通过对象属性查找的方式来进行逻辑判断,这种写法特别适合一元条件判断的情况。

  1. const actions = new Map([
  2. [1, ['processing','IndexPage']],
  3. [2, ['fail','FailPage']],
  4. [3, ['fail','FailPage']],
  5. [4, ['success','SuccessPage']],
  6. [5, ['cancel','CancelPage']],
  7. ['default', ['other','Index']]
  8. ])
  9. /**
  10. * 按钮点击事件
  11. * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
  12. */
  13. const onButtonClick = (status)=>{
  14. let action = actions.get(status) || actions.get('default')
  15. sendLog(action[0])
  16. jumpTo(action[1])
  17. }

我们需要把问题升级一下,以前按钮点击时候只需要判断status,现在还需要判断用户的身份:

  1. /**
  2. * 按钮点击事件
  3. * @param {number} status 活动状态:1开团进行中 2开团失败 3 开团成功 4 商品售罄 5 有库存未开团
  4. * @param {string} identity 身份标识:guest客态 master主态
  5. */
  6. const onButtonClick = (status,identity)=>{
  7. if(identity == 'guest'){
  8. if(status == 1){
  9. //do sth
  10. }else if(status == 2){
  11. //do sth
  12. }else if(status == 3){
  13. //do sth
  14. }else if(status == 4){
  15. //do sth
  16. }else if(status == 5){
  17. //do sth
  18. }else {
  19. //do sth
  20. }
  21. }else if(identity == 'master') {
  22. if(status == 1){
  23. //do sth
  24. }else if(status == 2){
  25. //do sth
  26. }else if(status == 3){
  27. //do sth
  28. }else if(status == 4){
  29. //do sth
  30. }else if(status == 5){
  31. //do sth
  32. }else {
  33. //do sth
  34. }
  35. }
  36. }

  二元判断时

  1. const actions = new Map([
  2. ['guest_1', ()=>{/*do sth*/}],
  3. ['guest_2', ()=>{/*do sth*/}],
  4. ['guest_3', ()=>{/*do sth*/}],
  5. ['guest_4', ()=>{/*do sth*/}],
  6. ['guest_5', ()=>{/*do sth*/}],
  7. ['master_1', ()=>{/*do sth*/}],
  8. ['master_2', ()=>{/*do sth*/}],
  9. ['master_3', ()=>{/*do sth*/}],
  10. ['master_4', ()=>{/*do sth*/}],
  11. ['master_5', ()=>{/*do sth*/}],
  12. ['default', ()=>{/*do sth*/}],
  13. ])
  14.  
  15. /**
  16. * 按钮点击事件
  17. * @param {string} identity 身份标识:guest客态 master主态
  18. * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 开团成功 4 商品售罄 5 有库存未开团
  19. */
  20. const onButtonClick = (identity,status)=>{
  21. let action = actions.get(`${identity}_${status}`) || actions.get('default')
  22. action.call(this)
  23. }

用Object对象来实现

  1. const actions = {
  2. 'guest_1':()=>{/*do sth*/},
  3. 'guest_2':()=>{/*do sth*/},
  4. //....
  5. }
  6.  
  7. const onButtonClick = (identity,status)=>{
  8. let action = actions[`${identity}_${status}`] || actions['default']
  9. action.call(this)
  10. }

用Map对象,以Object对象作为key:

  1. const actions = new Map([
  2. [{identity:'guest',status:1},()=>{/*do sth*/}],
  3. [{identity:'guest',status:2},()=>{/*do sth*/}],
  4. //...
  5. ])
  6.  
  7. const onButtonClick = (identity,status)=>{
  8. let action = [...actions].filter(([key,value])=>(key.identity == identity && key.status == status))
  9. action.forEach(([key,value])=>value.call(this))
  10. }

JavaScript 复杂判断的更优雅写法借鉴的更多相关文章

  1. JavaScript复杂判断的更优雅写法

    摘要: 写代码是一门艺术. 原文:JavaScript 复杂判断的更优雅写法 作者:Think. 公众号:大转转fe Fundebug经授权转载,版权归原作者所有. 前提 我们编写js代码时经常遇到复 ...

  2. JavaScript 复杂判断的更优雅写法

    我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得越来越臃 ...

  3. 【转】转自微信公众号 JavaScript 复杂判断的更优雅写法

    与微信公众号看到一篇js复杂判断的文章,对我启发很大,故转到博客园以供后期不断学习并应用于项目.原文地址:https://mp.weixin.qq.com/s/ClFDRj4MnAxv1dJ5VWKS ...

  4. JavaScript 复杂判断的优雅写法

    JavaScript 复杂判断的优雅写法 <div> <input type="button" name="btn" value=" ...

  5. C#中一种替换switch语句更优雅的写法

    今天在项目中遇到了使用switch语句判断条件,但问题是条件比较多,大概有几十个条件,满屏幕的case判断,是否有更优雅的写法替代switch语句呢? 假设有这样的一个场景:商场经常会根据情况采取不同 ...

  6. 使用 Promises 编写更优雅的 JavaScript 代码

    你可能已经无意中听说过 Promises,很多人都在讨论它,使用它,但你不知道为什么它们如此特别.难道你不能使用回调么?有什么了特别的?在本文中,我们一起来看看 Promises 是什么以及如何使用它 ...

  7. es6之更优雅的条件语句

    在使用JavaScript时,条件判断是经常会用到的,一些简单的判断条件还可以接受,当遇到比较复杂多重条件时就比较恶心了.这里使用es6的小技巧使判断更优雅. 1.使用 Arrary.includes ...

  8. jquery.form.js 让表单提交更优雅

    jquery.form.js 让表单提交更优雅.可以页面不刷新提交表单,比jQuery的ajax提交要功能强大. 1.引入 <script src="/src/jquery-1.9.1 ...

  9. JavaScript中判断变量类型最简洁的实现方法以及自动类型转换(#################################)

    这篇文章主要介绍了JavaScript中判断整字类型最简洁的实现方法,本文给出多个判断整数的方法,最后总结出一个最短.最简洁的实现方法,需要的朋友可以参考下 我们知道JavaScript提供了type ...

随机推荐

  1. Linux双网卡绑定和解除

    转载双网卡绑定和解除  一定要在服务管理中关闭NetworkManager服务并禁用自动启动,因为NetworkManager服务是实时生效的,一旦设置错,管理员就得回到机房接显示器配置网络连接. 以 ...

  2. MySQL5.7的并行复制

    MySQL5.6开始支持以schema为维度的并行复制,即如果binlog row event操作的是不同的schema的对象,在确定没有DDL和foreign key依赖的情况下,就可以实现并行复制 ...

  3. master-slave replication

    redis save 备份 恢复 root@ubuntu:/etc/init.d# find / -name dump.rdb |xargs ls -alt redis-cli save cp /va ...

  4. 十五、jenkins环境配置

    1. jenkins包下载,下载地址:https://jenkins.io/download/ 版本:Jenkins 2.134,下载war包 2. JDK下载:下载地址:http://www.ora ...

  5. bash中前后移动一个单词和删除单词的快捷键

    bash中一个很重要的快捷键,就是向后删除一个单词: ctrl+w=ctrl+W 一个字符一个字符的移动是: ctrl+f, ctrl+b 但是, 一个单词一个单词的移动是: (但是, 这个用得比较少 ...

  6. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_4_Iterator接口介绍

    collection集合中是没有索引的,不能使用普通的循环来便利它. 也是在util的包中 先判断集合中有没有元素 有元素就取出来,用next方法 使用接口来接受一个实现类,这就是多态

  7. 分布式ID生成 - 雪花算法

    雪花算法是一种生成分布式全局唯一ID的经典算法,关于雪花算法的解读网上多如牛毛,大多抄来抄去,这里请参考耕耘的小象大神的博客ID生成器,Twitter的雪花算法(Java) 网上的教程一般存在两个问题 ...

  8. Java8的I/O整理

    一.什么是I/O? Java的核心库java.io提供了全面的IO接口.包括:文件读写.标准设备输出等.Java中IO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入. 二.什 ...

  9. 编译的时候出现"/usr/bin/ld: cannot find -lz

    编译的时候出现"/usr/bin/ld: cannot find -lz"错误,需要安装zlib-dev这个包,在线安装命令为:apt-get install zlib1g-dev ...

  10. python基础-7.3模块 configparser logging subprocess os.system shutil

    1. configparser模块 configparser用于处理特定格式的文件,其本质上是利用open来操作文件. 继承至2版本 ConfigParser,实现了更多智能特征,实现更有可预见性,新 ...