写 JS 逻辑判断,不要只知道用 if-else 和 switch(转载)

优化 JavaScript 中 if-else 语句的替代方案 if-else 语句是在编程中经常使用的条件控制结构之一,用于根据条件的真假执行不同的代码块。在特定场景下,我们可以使用对象字面量或映射表、策略模式或函数式编程的条件判断来替代复杂的 if-else 语句。根据具体的需求和代码结构,选择合适的方案来优化代码。使用策略模式的好处是将不同的操作逻辑封装到独立的策略对象中,可以提高代码的可维护性和可扩展性。使用对象字面量或映射表的优点是可以将条件和操作直接映射起来,代码更加简洁和易读。如果有大量的条件需要处理,这种方式也可以提高代码的可维护性。 阅读详情

文章来自博客园前端小蜜蜂

如何优雅的写判断

我们在编写 JS 代码时,经常会遇到逻辑判断复杂的情况。一般情况下,可以用 if/else 或 switch 来实现多个条件判断,但会出现一个问题:随着逻辑复杂度的增加,代码中的 if/else 和 switch 会越来越臃肿。本文将带你尝试写出更优雅的判断逻辑。

比如说下面这样一段代码:

const onButtonClick = (status) => {
	  if (status == 1) {
	    sendLog('processing')
	    jumpTo('IndexPage')
	  } else if (status == 2) {
	    sendLog('fail')
	    jumpTo('FailPage')
	  } else if (status == 3) {
	    sendLog('fail')
	    jumpTo('FailPage')
	  } else if (status == 4) {
	    sendLog('success')
	    jumpTo('SuccessPage')
	  } else if (status == 5) {
	    sendLog('cancel')
	    jumpTo('CancelPage')
	  } else {
	    sendLog('other')
	    jumpTo('Index')
	  }
  }

你可以在代码中看到这个按钮的点击逻辑。根据活动状态的不同做两件事,发送日志埋点并跳转到相应的页面。很容易想到这段代码可以用 switch 重写如下:

const onButtonClick = (status) => {
  switch (status) {
    case 1:
      sendLog('processing')
      jumpTo('IndexPage')
      break
    case 2:
    case 3:
      sendLog('fail')
      jumpTo('FailPage')
      break
    case 4:
      sendLog('success')
      jumpTo('SuccessPage')
      break
    case 5:
      sendLog('cancel')
      jumpTo('CancelPage')
      break
    default:
      sendLog('other')
      jumpTo('Index')
      break
  }
}

好吧,看起来比 if/else 层次结构更清晰一些,细心的读者可能也发现了一个小窍门:case 2 和 case 3 的逻辑一样时,可以把前面的逻辑处理代码省略,case 2 会自动执行与 case 3 的逻辑。

不过,还有一个更简单的写法:

const actions = {
  '1': ['processing', 'IndexPage'],
  '2': ['fail', 'FailPage'],
  '3': ['fail', 'FailPage'],
  '4': ['success', 'SuccessPage'],
  '5': ['cancel', 'CancelPage'],
  default: ['other', 'Index'],
}

const onButtonClick = (status) => {
  let action = actions[status] || actions['default'],
    logName = action[0],
    pageName = action[1]
  sendLog(logName)
  jumpTo(pageName)
}

上面的代码看起来确实比较干净,这种方法的巧妙之处在于,它把判断条件作为对象的属性名,把处理逻辑作为对象的属性值。在点击按钮的时候,这种方法特别适用于单项条件判断的情况,即通过对象属性查找的方式进行逻辑判断。

这个方法很好,但是有没有其他的方法来编码呢?有的!

const actions = new Map([
  [1, ['processing', 'IndexPage']],
  [2, ['fail', 'FailPage']],
  [3, ['fail', 'FailPage']],
  [4, ['success', 'SuccessPage']],
  [5, ['cancel', 'CancelPage']],
  ['default', ['other', 'Index']],
])

const onButtonClick = (status) => {
  let action = actions.get(status) || actions.get('default')
  sendLog(action[0])
  jumpTo(action[1])
}

使用 Map 代替 Object 有很多优点,Map 对象和普通对象有的区别是:

一个对象通常有自己的原型,所以一个对象总是有一个“prototype”键
对象的键只能是一个字符串或符号,但 Map 的键可以是任何值
你可以通过使用 size 属性很容易得到 Map 中的键值对的数量,而一个对象中的键值对数量不能直接获取

现在我们来升级一下这个问题的难度。点击按钮时,不仅要判断状态,还要判断用户的身份。

const onButtonClick = (status, identity) => {
  if (identity == 'guest') {
    if (status == 1) {
      //do sth
    } else if (status == 2) {
      //do sth
    } else if (status == 3) {
      //do sth
    } else if (status == 4) {
      //do sth
    } else if (status == 5) {
      //do sth
    } else {
      //do sth
    }
  } else if (identity == 'master') {
    if (status == 1) {
      //do sth
    } else if (status == 2) {
      //do sth
    } else if (status == 3) {
      //do sth
    } else if (status == 4) {
      //do sth
    } else if (status == 5) {
      //do sth
    } else {
      //do sth
    }
  }
}

从上面的例子中可以看到,当你的逻辑升级到双重判断的时候,你的判断力就会加倍,你的代码就会加倍。

如何才能让代码更干净利落呢?

这里有一个解决方案。

const actions = new Map([
  ['guest_1', () => {}],
  ['guest_2', () => {}],
  ['guest_3', () => {}],
  ['guest_4', () => {}],
  ['guest_5', () => {}],
  ['master_1', () => {}],
  ['master_2', () => {}],
  ['master_3', () => {}],
  ['master_4', () => {}],
  ['master_5', () => {}],
  ['default', () => {}],
])

const onButtonClick = (identity, status) => {
  let action = actions.get(`${identity}_${status}`) || actions.get('default')
  action.call(this)
}

上述代码的核心逻辑是。将两个判断条件拼接成一个字符串作为 Map 的键,然后在查询时直接查询对应字符串的值。当然,我们也可以在这里把 Map 改成 Object。

const actions = {
  guest_1: () => {},
  guest_2: () => {},
  //....
}
const onButtonClick = (identity, status) => {
  let action = actions[`${identity}_${status}`] || actions['default']
  action.call(this)
}
如果读者觉得把查询拼成一个字符串有点尴尬,还有另一个解决办法,那就是用一个 Map 对象作为 key。

const actions = new Map([
  [{ identity: 'guest', status: 1 }, () => {}],
  [{ identity: 'guest', status: 2 }, () => {}],
  //...
])
const onButtonClick = (identity, status) => {
  let action = [...actions].filter(([key, value]) => key.identity == identity && key.status == status)
  action.forEach(([key, value]) => value.call(this))
}

这里你也可以看到 Map 和普通对象的区别,其中 Map 可以用任何类型的数据作为键。现在让我们把它的难度再提高一点。如果对于 guest 身份来说,状态 1-4 的处理逻辑是一样的呢?

最坏的情况是这样的(代码大量重复):

const actions = new Map([
  [{ identity: 'guest', status: 1 }, () => {}],
  [{ identity: 'guest', status: 2 }, () => {}],
  [{ identity: 'guest', status: 3 }, () => {}],
  [{ identity: 'guest', status: 4 }, () => {}],
  [{ identity: 'guest', status: 5 }, () => {}],
  //...
])
更好的方法是把处理逻辑函数分离出来:

const actions = () => {
  const functionA = () => {}
  const functionB = () => {}
  return new Map([
    [{ identity: 'guest', status: 1 }, functionA],
    [{ identity: 'guest', status: 2 }, functionA],
    [{ identity: 'guest', status: 3 }, functionA],
    [{ identity: 'guest', status: 4 }, functionA],
    [{ identity: 'guest', status: 5 }, functionB],
    //...
  ])
}

const onButtonClick = (identity, status) => {
  let action = [...actions()].filter(([key, value]) => key.identity == identity && key.status == status)
  action.forEach(([key, value]) => value.call(this))
}

这对于日常需求来说已经足够了,但是说真的,函数 A 被引用了 4 次,还是有点烦人。

如果事情真的变得很复杂,比如身份有 3 种,状态有 10 种,你需要定义 30 个处理逻辑,其中很多处理逻辑都是一样的,这似乎让人无法接受。

而你可以这样做:

const actions = () => {
  const functionA = () => {} // 逻辑处理 A
  const functionB = () => {} // 逻辑处理 B
  return new Map([
    [/^guest_[1-4]$/, functionA],
    [/^guest_5$/, functionB],
    //...
  ])
}

const onButtonClick = (identity, status) => {
  let action = [...actions()].filter(([key, value]) => key.test(`${identity}_${status}`))
  action.forEach(([key, value]) => value.call(this))
}

这时使用 Map 而不是 Object 的优势比较明显,因为可以用正则式作为键。

如果需求变成:所有的对 guest 操作都需要发送一个日志埋点,不同状态的 guest 可能有不同的逻辑处理,那么我们可以写成如下:

const actions = () => {
  const functionA = () => {} // 逻辑处理 A
  const functionB = () => {} // 逻辑处理 B
  const functionC = () => {} // 发送日志 C
  return new Map([
    [/^guest_[1-4]$/, functionA],
    [/^guest_5$/, functionB],
    [/^guest_.*$/, functionC],
    //...
  ])
}

const onButtonClick = (identity, status) => {
  let action = [...actions()].filter(([key, value]) => key.test(`${identity}_${status}`))
  action.forEach(([key, value]) => value.call(this))
}

这样一来,公共逻辑和单个逻辑可以同时执行。

总结

本文讲到了八种 JS 逻辑判断的写法,包括:

if/else
switch
单一判断:存储在 Object 中
单一判断:存储在 Map 对象中
多重判断:将条件串联成一个字符串,存储在 Object 中
多重判断:将条件连成一个字符串,存储在 Map 对象中
多重判断:把条件作为对象存储在 Map 中
多重判断:把条件写成正则式存储在 Map 中
今天就分享到这里,愿你今后的编码生活不仅仅只有 if/else 或 switch。

SAP销售订单POD实操:从VL01N创建到VLPOD差异处理,保姆级避坑指南 本文详细解析SAP销售订单POD全流程,从VL01N创建到VLPOD差异处理,提供保姆级避坑指南。涵盖核心业务逻辑、前置配置、销售订单创建、交货单处理及差异解决方案,帮助用户高效管理供应链执行环节,确保财务与物流的准确对接。 阅读详情

相关推荐

Abel逆变换及其求解方法

Abel逆变换常应用在轴对称的、光学薄的火焰、羽流或等离子体重建。

weixin_49783507的博客 8375

写 JS 逻辑判断,不要只知道用 if-else 和 switch

我们在编写 JS 代码时,经常会遇到逻辑判断复杂的情况。一般情况下,可以用 if/else 或 switch 来实现多个条件判断,但会出现一个问题:随着逻辑复杂度的增加,代码中的 if/else 和 switch 会越来越臃肿。本文将带你尝试写出更优雅的判断逻辑。 比如说下面这样一段代码: const onButtonClick = (status) => { if (status == 1) { sendLog('processing') jumpTo('IndexPa...

keocce的博客 251

【CADARXC++】ObjectArx2023 C++ CAD二次开发环境配置笔记

从官网或第三方平台下载以下AUtoCAD2023、VisualStudio2019和ObjectArx2023安装时请注意安装顺序。

BIMCATIA的博客 1790

js中if else写法优劣

在项目的js文件中看到有如下两种写法,如图: 支持第一种写法的理由是:如果以后有多层判断,当条件第一次不满足条件时就直接return false,以后的判断就不需要执行,可以减少不必要的代码校验。 支持第二种写法的理由是:如果以后有多层判断,第一种就会出现多个if else判断,代码写法看起来麻烦,而第二种需要写if语句即可。 我是支持第一种写法。不过我觉得支持第二种写法

你究竟是想一辈子卖糖水,还是希望获得改变世界的机会? 3104

Win11下CH340串口识别失败的终极排查指南:从驱动更新到硬件电路检查

本文提供了Windows 11系统下CH340串口芯片识别失败的全面排查指南。从驱动更新、系统设置等软件层面入手,逐步深入到USB线缆、电源测量等硬件连接检查,并重点剖析了硬件设计细节,如电源退耦电容容值对设备描述符请求的关键影响,最终帮助开发者系统性地定位并解决识别难题。

weixin_29174013的博客 592

【100%通过率】华为OD机试真题 Python 实现【投篮大赛】【2022.11 Q4 新题】

你现在是一场采用特殊赛制投篮大赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中ops[i]是你需要记录的第i项操作,ops遵循下述规则: 整数x-表示本回合新获得分数x “+” – 表示本回合新获得的得分是前两次得分的总和。 “D” – 表示本回合新获得的得分是前一次得分的两倍。 “C” – 表示本回合没有分数,并且前一次得分无效,将其从记录中移除。 请你返回记录中所有得分的总和。

MISAYAONE的博客 1万+

不用if,switch书写判断语句

前提 平时我们编写js代码遇到判断的情况下,通道使用if/else或者switch来实现条件判断,但有些业务场景的逻辑复杂度比较特殊,随着需求的更改,代码中的if/else/switch会越来越臃肿,本文就是教你如何优化的编写判断逻辑. 例子一: 先看代码 /** * @description 活动点击 * @param {Number | String} statu...

qq_31619295的博客 2661

【数字IC验证进阶】正则表达式(Regular Expression)快速入门指南

在芯片开发过程中,正则表达式的使用非常常见。初次上手晦涩难懂,多用几次爱不释手!

悟已往之不谏 知来者之可追 1441

代替多个if判断的另一种方法

代替多个if判断的另一种方法 对于if的使用大家都不陌生,也是js中常用语法,很好用,但是面对处理大量数据,需要多个if判断时,写在我们的项目中就显得low,自己写起来也有些吃力,这里推荐一个小技巧,利用json类型来处理它 举个小例子,大家可以根据项目情况来参考 传统方式代码 // ------------传统方法------------------ // 获得来的node数据,每次操作只返回一个node,比如省市区联级,点击一个级别就返回一个node co

潮汐海灵的博客 1631

FTU电科院检测学习笔记-规划

如果写到最后,还非常的有动力和兴趣,可能会举出一些特定的例子来,但不保证一定是这样。

sixtome 1103

Python爬虫实战:用最新技术高效下载摄影网站图片

本文将深入探讨如何利用Python最新技术栈构建一个功能完整的摄影网站图片爬虫。我们将使用异步编程、智能反爬策略和现代化工具,实现高效、可靠的图片下载系统。高性能异步架构:使用asyncio实现高并发下载智能反爬策略:支持多种反爬措施和浏览器模拟多网站适配:可解析多种摄影网站结构数据管理:完整的下载记录和统计功能扩展性强:支持代理、分布式等高级功能用户友好:提供进度显示和详细日志。

2201_76125261的博客 1645

关于if、switch的 javascript 习题

1.判断一个整数,属于哪个范围:大于0;小于0;等于0 需要注意=与==的区别,前者为赋值,后者为相等 var a = prompt('请输入一个整数'); if(a > 0){ alert('该整数大于0'); } else if(a == 0){ alert('该整数是0'); } ...

weixin_30511107的博客 362

国产麒麟V10系统命令大全,100个实用命令助你玩转系统!

国产麒麟V10系统命令大全,100个实用命令助你玩转系统!

网络技术联盟站 1913

编写高质量可维护的代码之优化逻辑判断

编写高质量可维护的代码之优化逻辑判断前言JavaScript 语法篇试试 Array.includes ~函数默认值策略模式优化分支逻辑处理框架篇之 React JSX 逻辑判断优化If 标签For 标签With 标签 这里是转载于掘金上看到的文章 转载地址:https://juejin.im/post/6859125809655840776 作者:政采云前端团队 前言 if else、switch case 是日常开发中最常见的条件判断语句,这种看似简单的语句,当遇到复杂的业务场景时,如果处理不善,就会出

yjl23332的博客 442

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

javascript里判断的多种写法

JavaScript复杂判断的更优雅写法 摘要: 写代码是一门艺术。 原文:JavaScript 复杂判断的更优雅写法 作者:Think. Fundebug经授权转载,版权归原作者所有。 前提 我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得...

分享技术,前沿人工智能动态 1725

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

兀键和6键怎么判断_JavaScript 复杂判断的更优雅写法

转载:JavaScript 复杂判断的更优雅写法 作者:Think.出处:掘金前提 我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得越来越臃肿,越来越看不懂,那么如何更优雅的写判断逻辑,本文带你试一下。 举个例子先看一段代码/** * 按钮点击事件 *...

weixin_34442022的博客 149

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

2016年2月26日----Javascript逻辑判断语句

---Javascript逻辑判断语句 --条件语句用于基于不用的条件来执行不同的动作 --if:只有当指定条件为true时,使用该语句来执行代码 --if...else:当条件为true时执行代码,当条件为false时执行其他代码 --if...else if...else:使用该语句来选择多个代码块之一来执行 --switch:只用该语句来选择多个代码块之一来执行 ---Java...

weixin_33775582的博客 87

JS-4-if

流程控制结构1 顺序结构 alert(10); alert(20);2 分支结构(选择结构) * IF 2.1 if(条件) { 条件成立时执行的语句 } else { 条件不成立时执行的语句 } <script ty...

weixin_30715523的博客 76

javascript:多重条件判断

javascript 是一门精巧的语言,可大可小,可伸可缩,如意金箍棒一般,运用恰当,可敌千夫。比如一个场景,有的人要写上百行代码,但是有的人寥寥几笔即可实现,思路就在弹指间。要想学好一门语言,就要掌握其要义,归纳其精髓,方可如鱼得水,运筹帷幄。 js在开发大型组件库的时候经常会碰到很多的逻辑分支情况。比如博客园的编辑框编写: [task]if(target === "font"){ som...

weixin_30339969的博客 1949

从零开始学前端 - 11. JS语句 - 循环语句、条件语句、中断语句等

JS流程控制。 从零开始学前端 - 11. JS语句 - 循环语句、条件语句、中断语句等 一、 条件语句 1. if-else 2.switch-case 二、循环语句 1. for循环 2. for in 循环 3. while 循环 4. do while 循环 三、中断语句 1. break 2. continue 3. return 四、错误语句 1. throw 2. try_catch_finally

qq_39506551的博客 758

javascript基础知识(7) 条件判断

JavaScript使用if () { ... } else { ... }来进行条件判断。例如,根据年龄显示不同内容,可以用if语句实现如下: var age = 20; if (age >= 18) { // 如果age >= 18为true,则执行if语句块 alert('adult'); } else { // 否则执行else语句块 a...

weixin_30731287的博客 68

js 中的流程控制-条件语句

条件语句: if(exp)执行一句代码 1 <script> 2 var x = 1 ; 3 if(x == 1 ) //当if判断语句结果是true 或者 false 当判断结果等于true的时候,执行一句语句 4 document.write("x真的等于1") //=>x真的等于1 5 </scri...

weixin_30949361的博客 65

6.2.2 javascript 流程控制语句

<script type=> var ji = 20; if(ji >= 20){   console.log('恭喜你!') }else{   console.log('xxxxx') } if() {   xxx } else if () {     xxx }else if (){   xxx }else{   xxx } 浏览器解析代...

weixin_30877493的博客 162

ArkTS基础语法:变量与数据类型——构建类型安全的鸿蒙应用基石

在软件开发的历史演进中,动态类型语言(如JavaScript)以其灵活性和快速开发能力赢得了广泛市场,但运行时类型错误始终是困扰开发者的头号难题。据统计,生产环境中约15%的Bug源于类型不匹配、空值访问或属性不存在等类型相关问题,这些问题在编译期无法发现,只能在运行时暴露,修复成本随项目规模呈指数级增长。HarmonyOS推出的ArkTS语言,基于TypeScript构建并进行了针对性优化,其核心设计哲学之一就是"编译期类型安全"。与TypeScript相比,ArkTS进一步禁用了any。

从事移动开发八年,csdn博客专家,阿里云特邀专家,华为云云享专家,高级网络信息安全工程师,大数据工程师(高级),python技术开发(高级),HarmonyOS 应用开发者高级认证,现在某学校任教。 1万+

JavaSE『学习笔记』

本教程以 JDK8 为主,新版本与新特性以介绍与使用为辅。

小哞^同^学的技术博客 1237

js条件判断语句switch

语法 1、switch后面写的是表达式 2、case后面的返回值代表的是表达式的返回值,当表达式的返回值与任意一个case后面的值相同,就会执行该case后面的代码段,然后将返回值返回出去 3、如果没有满足全部case后面的返回值,那么就会返回default后面代码段的值,default就是设置默认值的地方 switch (表达式){ case 返回值1:{ 代码.. ... .. break; } case 返回值2:{ 代码.. ... .. break; } case 返回值3:{ 代码.. ..

果冻 3646
上一篇: js 对象深复制(深拷贝)
下一篇: javaScript中的set和get访问器属性
MaxLoongLvs
博客等级 码龄9年 226粉丝 170原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值