【面试题】如何替换项目中的if-else和switch

news2025/7/7 9:07:41

给大家推荐一个实用面试题库

1、前端面试题库面试必备)            推荐:★★★★★

地址:前端面试题库

在项目中,往往会看到很多的if-else或者switch,项目会变得很臃肿,而且不易阅读,那么今天我们就来讲讲优化方案

例如,假设我们有一个函数,它接受一个数字参数并返回其实际含义。使用 if/else 语句,它看起来像这样:

function getTranslation(type) {
  if (type === 4) {
    return "forbidden_area";
  } else if (type === 6) {
    return "elevator_area";
  } else if (type === 7) {
    return "dangerous_area";
  } else if (type === 10) {
    return "restricted_area";
  }
​
  return "other_area";
}
复制代码

这不是很好。它可读性差。

我们可以通过使用 switch 语句优化,如下所示:

function getTranslation(type) {
  switch (type) {
    case 4:
      return "forbidden_area";
    case 6:
      return "elevator_area";
    case 7:
      return "dangerous_area";
    case 10:
      return "restricted_area";
    default:
      return "other_area";
  }
}
复制代码

但这仍然没有什么可读性。switch 语句也容易出错。

在这种情况下,我们只是返回一个值,但是当你具有更复杂的功能时,很容易错过 break 语句并引入错误。

替代方案

你可以使用对象以更简洁的方式实现与上述相同的功能。让我们看一个例子:

function getTranslation(type) {
  const types = {
    4: 'forbidden_area',
    6: 'elevator_area',
    7: 'dangerous_area',
    10: 'restricted_area'
  }
  return types[type] ?? 'other_area'
}
复制代码

我们有一个对象,其中键是条件,值是响应。然后我们可以使用方括号符号从传入的参数中选择对象的正确值。

函数中return types[type] ?? 'other_area'使用无效合并来分配默认响应。这意味着如果 types[type]为 null 或undefined(但不是 false 或 0 ),则返回默认字符串“other_area”。

|| vs ??

||??都是指定默认值

读取对象属性的时候,如果某个属性的值是nullundefined,有时候需要为它们指定默认值。常见做法是通过||运算符指定默认值

const headerText = response.settings.headerText || 'Hello, world!';
const animationDuration = response.settings.animationDuration || 300;
const showSplashScreen = response.settings.showSplashScreen || true;
复制代码

上面的三行代码都通过||运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为nullundefined,默认值就会生效,但是属性的值如果为空字符串或false0,默认值也会生效。

为了避免这种情况,ES2020 引入了一个新的 Null 判断运算符??。它的行为类似||,但是只有运算符左侧的值为nullundefined时,才会返回右侧的值。而||是运算符左侧的值为nullundefined0''NaN 时,都会返回右侧的值!

更复杂的逻辑

有时你可能需要在你的条件中执行一些更复杂的逻辑。为此,你可以将函数作为值传递给对象键并执行响应:

function calculate(action, num1, num2) {
  const actions = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
    multiply: (a, b) => a * b,
    divide: (a, b) => a / b,
  };
​
  return actions[action]?.(num1, num2) ?? "Calculation is not recognised";
}
复制代码

?.有不懂的话,可以先看下面,我们正在选择我们想要做的计算并执行响应,传递两个数字。你可以使用可选链接(最后一行代码中的 ?.)来仅执行已定义的响应。否则,将使用默认的返回字符串。

如果函数里的逻辑足够复杂也可以把函数提取出来

function add(num1, num2) {
  return num1 + num2
}
function subtract(num1, num2) {
  return num1 - num2
}
function multiply(num1, num2) {
  return num1 * num2
}
function divide(num1, num2) {
  return num1 / num2
}
function calculate(action, num1, num2) {
  const actions = {
    add,
    subtract,
    multiply,
    divide
  }
​
  return actions[action]?.(num1, num2) ?? 'Calculation is not recognised'
}
复制代码

?.的说明

编程实务中,如果读取对象内部的某个属性,往往需要判断一下,属性的上层对象是否存在。比如,读取message.body.user.firstName这个属性,安全的写法是写成下面这样。

// 错误的写法
const  firstName = message.body.user.firstName || 'default';
​
// 正确的写法
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';
复制代码

上面例子中,firstName属性在对象的第四层,所以需要判断四次,每一层是否有值。

这样的层层判断非常麻烦,因此 ES2020 引入了“链判断运算符”(optional chaining operator)?.,简化上面的写法。

const firstName = message?.body?.user?.firstName || 'default';
复制代码

上面代码使用了?.运算符,直接在链式调用的时候判断,左侧的对象是否为nullundefined。如果是的,就不再往下运算,而是返回undefined

下面是判断对象方法是否存在,如果存在就立即执行的例子。

iterator.return?.()
复制代码

上面代码中,iterator.return如果有定义,就会调用该方法,否则iterator.return直接返回undefined,不再执行?.后面的部分。

下面是?.运算符常见形式,以及不使用该运算符时的等价形式。

a?.b
// 等同于
a == null ? undefined : a.b
​
a?.[x]
// 等同于
a == null ? undefined : a[x]
​
a?.b()
// 等同于
a == null ? undefined : a.b()
​
a?.()
// 等同于
a == null ? undefined : a()
复制代码

上面代码中,特别注意后两种形式,如果a?.b()a?.()。如果a?.b()里面的a.b有值,但不是函数,不可调用,那么a?.b()是会报错的。a?.()也是如此,如果a不是nullundefined,但也不是函数,那么a?.()会报错。

 

给大家推荐一个实用面试题库

1、前端面试题库面试必备)            推荐:★★★★★

地址:前端面试题库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/7025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

速溶颗粒:实验中的好伙伴

缓冲溶液 (buffer solution) 通常是由弱酸及其盐、弱碱及其盐组成的混合溶液,能在一定程度上抵消、减轻外加强酸或强碱对溶液酸碱度的影响,从而保持溶液的 pH 值相对稳定。 传统的缓冲液配制过程可简单概括为计算——称量——溶解——定容。而生物学上常…

windows10提权

参照tryhackme的win10提权靶场 靶场,地址 里面共描述了服务路径,文件权限,计划任务,令牌窃取,图形化软件,应用组件安装等,这里只有令牌窃取需要管理员Administrator权限,值得注意的是…

向毕业妥协系列之机器学习笔记:无监督学习-聚类

目录 序言 一.什么是聚类 二.K-means算法 三.优化目标 四.初始化K-means 五.选择聚类数量(k?) 序言 第三课这块要学习的几块知识如下: 在学完监督学习之后,接下来我们要学习的东西分别是聚类,异常检测&#xf…

Spring 源码阅读 74:事务管理的原理 - BeanFactoryTransactionAttributeSourceAdvisor 分析

本文通过对 BeanFactoryTransactionAttributeSourceAdvisor 类的分析,了解了 Spring 是如何通过 AOP 来完成事务的管理的,本文的内容需要你对 Spring 的 AOP 的实现原理有一定的了解。 基于 Spring Framework v5.2.6.RELEASE 概述 Spring 的事务管理基于…

基于 Flask-Admin 与 AdminLTE 构建通用后台管理系统

Flask-Admin 是什么? Flask-Admin 官网文档中给出了其功能定位: Why Flask-Admin? In a world of micro-services and APIs, Flask-Admin solves the boring problem of building an admin interface on top of an existing data model. With little e…

SAP 公司代码全局参数设置及其意义

在SAP中配置公司时,会配置公司的全局参数,但这些参数具体的意思是什么估计很多同学都搞不懂,我也找了下资料,贴出来供大家参考。 设置参数路径:IMG→财务会计→财务会计全局设置→公司代码的全球参数→输入全局参数 账…

教你几个手机识别图片中的文字小技巧

平时我们在工作,有时候会拿到需要录入的纸质文件,如果我们使用双手逐一对照录入的话,就太浪费时间了。其实还有一个更简单的方法,就是将需要录入的文件拍摄下来,借助工具将图片内容转写为文字出来,再将其复…

Python Flask框架-开发简单博客-认证蓝图

作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,在于他所拥有的。可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。我的…

最新定制的安卓项目及设计报告——仿番茄小说APP

已录演示视频,想看演示视频的可以私我 《移动应用开发实践》实践报告 APP名称: 番茄免费小说 要求: 格式:宋体,小四号字;首行缩进;行距:1.5倍。 每人独立完成Android App的设计…

三步学会如何构建平衡二叉树(简单好理解)

何为平衡二叉树? 首先回顾一下,什么是平衡二叉树(亦被称为AVL树,Adelson-Velskii and Landis)。平衡二叉树主要具有以下三个特点: 1. 平衡二叉树首先要符合搜索二叉树的特点:即左子树的值比根节点小&…

排序算法之归并排序

目录 归并排序递归实现 思想 图解 代码 归并排序的非递归版本 基本思想: 代码 归并排序递归实现 思想 最主要的相当于二叉树遍历中的后序遍历。 ①将数组分割成多个小区间(当只有一个元素或者并不存在的时候就不用再分割了) ②对每一…

某工控图片上传服务 CPU 爆高分析

一:背景 1.讲故事 今天给大家带来一个入门级的 CPU 爆高案例,前段时间有位朋友找到我,说他的程序间歇性的 CPU 爆高,不知道是啥情况,让我帮忙看下,既然找到我,那就用 WinDbg 看一下。 二&…

Linux进程概念和控制(必备知识)

文章目录1、冯诺依曼体系结构2、操作系统3、进程<1>进程的创建<2>进程查看<3>进程状态<4>进程优先级<5> 进程地址空间4、环境变量5、进程控制<1>进程终止<2>进程等待<3>进程替换1、冯诺依曼体系结构 我们常见的计算机&#x…

软考 - 软件工程

软件过程基本概述 基本要素 方法工具过程 软件过程模型 能力成熟度模型CMM 能力成熟度模型CMMI 统一过程UP模型 针对大型项目 三大特别 用例和风险驱动以架构为中心迭代并且增量 四个阶段 起始&#xff1a;确认需求和风险评估精化&#xff1a;核心架构设计构建&#xff1a;构…

Linux内核开发 | Linux内核目录结构分析(5.4.32)

文章目录1. arch2. block3. certs4. crypto5. Documentation6. drivers7. fs8. include9. init10. ipc11. kernel12. lib13. mm14. net15. samples16. scripts17. security18. sound19. tools20. usr21. virt本文以Linux主线5.4.32内核版本进行分析。1. arch 该目录下包含了li…

【ROS】机械人开发--ROS工作空间与功能包

机械人开发--ROS工作空间与功能包一、ROS工作空间1.1 概念1.2 创建工作空间1.3 编译工作空间1.4 设置环境变量1.5 添加环境变量二、功能包2.1 概念2.2 功能包的内容2.3 创建功能包三、CMakeLists.txt文件四、package.xml文件一、ROS工作空间 1.1 概念 工作空间&#xff08;wo…

以“新IT”助“数智融合”,联想推开“智能化转型”下半场的大门

作者 | 曾响铃 文 | 响铃说 近年来&#xff0c;我国对数字化的重视达到前所未有的高度&#xff0c;从“十四五”规划纲要首次将数字经济单独列为一篇&#xff1b;到二十大报告中指出&#xff1a;“坚持把发展经济的着力点放在实体经济上”、“促进数字经济和实体经济深度融合…

SpringMVC学习篇(五)

SpringMVC之json数据传递 1.1 准备工作 1.1.1 导入lombok依赖(方便写实体类) <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency>1.1.2 导入mvc js…

mysql经典案例带解析(你没见过的全新版本)55题

首先给出初始表格 表格创建命令 create table emp(id int primary key auto_increment,name varchar(20),job varchar(20),manager int,hiredate date,sal double(8,2),comm double(6,2),dept_id int)charsetutf8;create table dept(id int primary key auto_increment,nam…

AcrelEMS-BP生物制药工厂能效管理系统

安科瑞 华楠 聚焦全厂能源采集、监控、分析、调度,降本提效,实现企业双碳目标;致力于全域化设备监视、巡检、故障报警、工单管理,运维优化,提升设备使用效率。 综合自动化系统 110kV及以下变电站综合自动化系统实现遥测、遥信、遥控、事故追忆、故障录波、安全防护、上传调度 …