Javascript 地狱级的if else / switch case该如何优化?

news2024/11/18 19:58:15

目录

问题

一、7大策略优化 

1.单个if语句优化 

2.if/else语句优化

3.多条件判断

4.多个 if else 嵌套优化策略 

问题场景

如何优化 

1.使用卫语句

2. try catch优化

3. 可选链 optional chaining

5.Map优化

场景实战

6.策略模式优化 

7.复杂二维数组策略模式

优化点

二、总结思考

往期回顾


问题

我们在项目开发过程中,经常要做各种条件判断,不同条件执行不同的逻辑代码,但随着业务的越来越复杂,这种if else / switch case堆得越来越多,下面我介绍7种优化方案,大家根据实际场景选择优化,不足之处,请大家补充。

一、7大策略优化 

1.单个if语句优化 

 使用&& || 优化

if (e) { 
  this.getUser()
 }

优化后

e && this.getUser()

2.if/else语句优化

 如果遇到单一条件逻辑,我们可以用三元表达式优化,比如如下代码:

// 原逻辑
if ( type === 1) {
  console.log(1)
} else {
  console.log(1)
}

// 优化后
type === 1 ? console.log(1) : console.log(1)

3.多条件判断

 如果条件较多,那我们可以使用Array.includes(),比如如下代码:

// switch场景
switch (type) {
	case 0:
	// 场景0
	break
	case 1:
  // 场景1
	break
	case 2:
	// 场景2
	break
	case 3:
	// 场景3
	break
 // 场景...
	default:
}

// if else 场景
if (type === 0) {
	// do sth ...
} else if (type === 1) {
	// do sth ...
} else if (type === 2) {
	// do sth ...
} else if (type === 3) {
	// do sth ...
}

用 includes重构后,如下

let types = [1,2,3,4];
if (types.includes(type)) {
  // do sth ...
}

4.多个 if else 嵌套优化策略 

问题场景

如果页面的展示内容规则是,后端返回某个字段则展示,不返回则不展示,比如那种层层嵌套的json数据,可能嵌套十几层,下面我做个简单案例:

// 存在habby的数据
let res = {
  status: 200,
  msg: "success",
  data: {
    userInfo: {
      name: "fuchaoyang",
      hobby: ["打篮球", "唱歌", "学习"],
    },
  },
};
// 不存在habby的数据
let res2 = {
  status: 200,
  msg: "success",
  data: {
    userInfo: {
      name: "fuchaoyang",
    },
  },
};

那么我们可能就会写出如下的代码

function getHobby(res) {
  if (res.data) {
  if (res.data.userInfo) {
      if (Array.isArray(res.data.userInfo.hobby)) {
        if (res.data.userInfo.hobby.length) {
          // 进行业务逻辑操作
          return res.data.userInfo.hobby;
        } else {
          return "hobby字段为空";
        }
      } else {
        return "hobby字段不是一个数组";
      }
    } else {
      return "userInfo字段不存在";
    }
  } else {
    return "data字段不存在";
  }
}

注意: if else 一般不建议嵌套超过三层,如果一段代码存在过多的 if else 嵌套,代码的可读性就会急速下降,后期维护难度也大大提高,应该尽量避免过多的 if else 嵌套。

如何优化 

1.使用卫语句
if (!res.data) return "data字段不存在";
if (!res.data.userInfo) return "userInfo字段不存在";
if (!Array.isArray(res.data.userInfo.boddy)) return "hobby字段不是一个数组";
if (res.data.userInfo.hobby.length) {
  // 进行业务逻辑操作
}
2. try catch优化
try {
  // 有可能出现错误的代码写在这里
  if (res.data.userInfo.hobby.length) {
    // 进行业务逻辑操作
  }
} catch (error) {
  // 出错后的处理写在这里
}

注意:如果 try 中的代码没有出错,则程序正常运行 try 中的内容后,不会执行 catch 中的内容
如果 try 中的代码出错,程序立即跳入 catch 中继续执行,try 中出错后的程序就不再执行了。

3. 可选链 optional chaining

对一个空值进行属性读取时,程序会抛出异常;在多级嵌套的对象中取属性值的时候,更容易出现这个问题,为了保证程序的健壮性,就需要确保对象不为空时,再读取下一级的值 。

// 可选链优化
if (res?.data?.userInfo?.hobby?.length) {
  // 进行业务逻辑操作
}

注意:操作符 *?.* 会检查操作符左边的值是否是空值。如果是 null 或 undefined,这个表达式就终止然后返回 undefined。否则,这个表达式继续执行检查 。

5.Map优化

 Map 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。

场景实战

比如我们在搭建前端架构时,需要在拦截器中根据不同的异常码,那么我们就可以定义一个map,里面存储对应的状态码和相应的操作。

let statusMap = new Map([
	[200, do200Case],
	[301, do301Case],
	[400, do400Case],
	[401, do401Case],
  [500, do500Case],
  [503, do503Case]
])
// 定义对应的方法:
function do200Case(){
  // 状态码 200 逻辑处理
}
function do301Case(){
 // 状态码 301 逻辑处理
}
function do400Case(){
 // 状态码 400 逻辑处理
}
function do401Case(){
 // 状态码 401 逻辑处理
}
function do500Case(){
 // 状态码 500 逻辑处理
}
function do503Case(){
 // 状态码 503 逻辑处理
}
//当符合某个状态时,执行相应的操作
statusMap.get(type)()

缺点:如果状态很多,就要写很多对应的函数,造成重复切单一的行为操作。

6.策略模式优化 

实现的原理是存到对象里面,然后利用用对象的多态性来实现,比如如下代码:

// 根据职业描述
function getInfomation(name) {
    const describeMap = {
      teacher: () => console.log("我是学校的老师"),
      chef: () => console.log("我是酒店的大厨"),
      soldier: () => console.log("我是保家卫国的军人"),
      driver: () => console.log("我是滴滴司机"),
      waiter: () => console.log("我是酒店服务员"),
    };
   return describeMap[name] ? describeMap[name]() : console.log("没找到你需要的职位描述!");
}
getInfomation('teacher');
getInfomation('default');

我们就只需通过getInfomation函数接收到的参数去获取describeMap对象中对应的值,如果该值存在就运行该值(因为值是一个函数)。

这样一来原本的 if 分支判断就转换成了简单的key value对应值,条件与处理函数一一对应,一目了然。

7.复杂二维数组策略模式

对于结构的代码,我们可以引入二维数组来进行优化:

const describeMapArrary = [
    [
        (name) => name === 'teacher', // 判断条件
        () => {
          // 业务逻辑处理...
          console.log('teacher',"我是学校的老师") // 执行函数
        }
    ],
    [
        (name) => name === 'chef', 
        () => {
           // 业务逻辑处理...
          console.log('chef',"我是酒店的大厨")
        }
    ],
    [
        (name) => name === 'soldier', 
        () => {
          // 业务逻辑处理...
          console.log('soldier',"我是保家卫国的军人")
        }
    ],
    [
        (name) => name === 'driver', 
        () => {
          // 业务逻辑处理...
          console.log('driver',"我是滴滴司机");
          return 'driver 我是driver场景的返回值'; // 有返回值场景
        }
    ],
];
    
function getDescribeName(name) {
    // 获取符合条件的子数组
    const getDescribe = describeMapArrary.find((item) => item[0](name));
    // 子数组存在则运行子数组中的第二个元素(执行函数)
    return getDescribe ? getDescribe[1]() : console.log('default',"没找到你需要的职位描述!");
}
getDescribeName('soldier'); // 查询map中存在的条件
console.log(getDescribeName('driver')); // 查询map中存在的条件并返回函数处理值
getDescribeName('fuchaoyang'); // 查询map中不存在的条件

对象是一个独立的结构,我们将它抽离到了函数体之外,这样对于后期维护更加友好。

优化点

使用模块化开发可以将这个map对象写进一个单独的js文件,之后在需要使用的地方导入即可。

二、总结思考

1.多重判断时使用 Array.includes

2.使用对象或使用 map 结构来优化if else,而不是 Switch 语句

3.更少的嵌套,尽早 return ,用卫语句优化

4.项目中需要大量算法,大量匹配模式时,可以考虑策略模式

5.使用默认参数和解构

讲到这里,相信大家对前端if else / switch case的优化有了新的认识,如有不足之处,请大家补充,欢迎在评论区交流。

如果文章对你有所帮助,❤️关注+点赞❤️鼓励一下博主会持续更新。。。。

我的个人博客:https://code-nav.top

往期回顾

 css实现元素居中的6种方法 

Angular8升级至Angular13遇到的问题

前端vscode必备插件(强烈推荐)

Webpack性能优化

vite构建如何兼容低版本浏览器

前端性能优化9大策略(面试一网打尽)!

vue3.x使用prerender-spa-plugin预渲染达到SEO优化

 vite构建打包性能优化

 vue3.x使用prerender-spa-plugin预渲染达到SEO优化

 ES6实用的技巧和方法有哪些?

 css超出部分显示省略号

vue3使用i18n 实现国际化

vue3中使用prismjs或者highlight.js实现代码高亮

什么是 XSS 攻击?什么是 CSRF?什么是点击劫持?如何防御

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

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

相关文章

Fpga开发笔记(一):高云FPGA芯片介绍,入手开发板套件、核心板和底板介绍

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/135551179 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

趣味编程:少儿编程思维的启蒙之旅

随着科技的发展,编程已经成为了一项重要的技能。越来越多的家长开始关注少儿编程教育,希望孩子能在轻松愉快的氛围中学习编程知识,培养编程思维。而图形化编程工具Scratch正是这样一款专为少儿打造的编程软件,让孩子们在趣味编程的…

leetcode第365题:水壶问题

有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 targetCapacity 升。 如果可以得到 targetCapacity 升水,最后请用以上水壶中的一或两个来盛放取得的 targetCapacity 升水。 你可以&a…

关于霍尔电流传感器在电池柜监测中的设计与应用-安科瑞 蒋静

摘要:本文分析了霍尔电流传感器的工作原理,浅谈其在电池柜监测中的应用。 关键词:霍尔电流传感器 工作原理 充放电电流 电池柜 引言 大多数的工厂里,使用到的电池柜,它是将许多的新组装的电池一起进行充电的&…

OpenCV-Python(40):光流算法

目标 光流的概念以及Lucas-Kanade 光流法使用函数cv2.calcOpticalFlowPyrLK() 对图像中的特征点进行跟踪 光流 介绍 由于目标对象或者摄像机的移动造成的图像对象在连续两帧图像中的移动被称为光流。它是一个2D 向量场,可以用来显示一个点从第一帧图像到第二帧图像…

使用 raise_exception 装饰器,简化 if not ... raise ... 抛出异常的过程

目录 一、前置说明1、总体目录2、相关回顾3、本节目标 二、操作步骤1、项目目录2、代码实现3、测试代码4、日志输出 三、后置说明1、要点小结2、下节准备 一、前置说明 1、总体目录 《 pyparamvalidate 参数校验器,从编码到发布全过程》 2、相关回顾 python 装饰…

多角度展文明风采!成都市第二届公益短视频大赛落幕

近日,“金芙蓉文明让生活更美好”成都市第二届公益短视频大赛揭晓获奖名单,170余部作品脱颖而出。此次大赛共收到700余部参赛作品,以不同手法、从不同角度描绘文明成都。 用短视频弘扬社会主义核心价值观 以真实故事为原型引发更多人共鸣 …

Android-常用数据结构和控件

HashMap 的原理 HashMap 的内部可以看做数组链表的复合结构。数组被分为一个个的桶(bucket)。哈希值决定了键值对在数组中的寻址。具有相同哈希值的键值对会组成链表。需要注意的是当链表长度超过阈值(默认是8)的时候会触发树化,链表会变成树形结构。 把握HashMap的…

线性代数基础【4】线性方程组

第四章 线性方程组 一、线性方程组的基本概念与表达形式 二、线性方程组解的基本定理 定理1 设A为mXn矩阵,则 (1)齐次线性方程组AX0 只有零解的充分必要条件是r(A)n; (2)齐次线性方程组AX0 有非零解(或有无数个解)的充分必要条件是r(A)<n 推论1 设A为n阶矩阵,则…

干货速递|用需求在环仿真扩展基于模型的系统工程实践:起落架系统案例

摘要 仿真已经成为大多数行业大规模采用基于模型的系统工程(MBSE)和基于模型的设计(MBD)工具的至关重要的因素。与此同时,实用的需求工程工具在以文档需求规格为主的生命周期管理之外并未得到显著发展,这使…

【CSS】首个字符占用多行,并自定义样式

效果 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>首字母大写</title><style&…

消息的发送与接收

消息的发送与接收 消息的发送与接收不仅仅是在于聊天功能的实现。其实还有很多种情况也算"消息的发送与接收"。而且我们还可以通过多种方法去实现。我们可以基于实际情况来选择。 WebSocket实现 node做后端。找了好多&#xff0c;前端页面总是用到了jQuery&#x…

AMC8历年详细考点分类,都熟悉了考高分不成问题(2024年也适用)

还有四天&#xff0c;2024年AMC8美国数学思维活动&#xff08;竞赛&#xff09;就要正式开始了&#xff0c;这两天有多位家长咨询六分成长&#xff0c;想了解AMC8的主要考点&#xff0c;或者说经常考的内容。 根据2000-2023年这23年的真题分析&#xff0c;AMC8试题的考点可以分…

Java开发+Intellij-idea+Maven+工程构建

Java开发Intellij-ideaMaven工程构建 Intellij-idea是一款流行的Java集成开发环境&#xff0c;它支持Maven作为项目管理和构建工具。Maven可以帮助开发者自动下载项目依赖的jar包&#xff0c;执行编译、测试、打包等生命周期任务。本资源将介绍如何在Intellij-idea中创建、导入…

MATLAB二维与三维绘图实验

本文MATLAB源码&#xff0c;下载后直接打开运行即可[点击跳转下载]-附实验报告https://download.csdn.net/download/Coin_Collecter/88740747 一、实验目的 掌握图形对象属性的基本操作。掌握利用图形对象进行绘图操作的方法。 二、实验内容 利用图形对象绘制曲线&#xff…

亚信安慧AntDB超融合框架——数智化时代数据库管理的新里程碑

在信息科技飞速发展的时代&#xff0c;亚信科技AntDB团队提出了一项颠覆性的“超融合”理念&#xff0c;旨在满足企业日益增长的复杂混合负载和多样化数据类型的业务需求。这一创新性框架的核心思想在于融合多引擎和多能力&#xff0c;充分发挥分布式数据库引擎的架构优势&…

钉钉逐浪AI Agent

文&#xff5c;郝 鑫 编&#xff5c;刘雨琦 “大公司代表落后生产力&#xff0c;是慢半拍的”&#xff0c;“小创新靠大厂&#xff0c;大创新仍然要靠小厂”&#xff0c;这是以李彦宏和王小川为代表的创业老炮&#xff0c;在2023年总结出来的创新规律&#xff0c;从移动互…

图形化编程:以Scratch引领少儿编程思维启蒙之旅

在21世纪科技飞速发展的今天&#xff0c;编程教育已经成为培养未来人才的重要途径。而“少儿编程”这一概念的提出&#xff0c;正是为了让孩子们从小接触并理解计算机逻辑&#xff0c;锻炼他们的创新思维与问题解决能力。其中&#xff0c;图形化编程以其直观易懂、趣味性强的特…

手把手教你VS code文件如何在顶部自动生成作者,修改日期等信息

1、安装插件KoroFileHeader 2、左下角选择管理---设置---输入"fileheader"---点击"在setting.json中编辑" 输入"fileheader"-点击"在setting.json中编辑" fileheader 必须的基础配置: 头部注释模板与函数注释模板 复制&#xff1a;…

C++(1) —— 基础语法入门

目录 一、C初识 1.1 第一个C程序 1.2 注释 1.3 变量 1.4 常量 1.5 关键字 1.6 标识符命名规则 二、数据类型 2.1 整型 2.2 sizeof 关键字 2.3 实型&#xff08;浮点型&#xff09; 2.4 字符型 2.5 转义字符 2.6 字符串型 2.7 布尔类型 bool 2.8 数据的输入 三…