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

目录

问题

一、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的优化有了新的认识,如有不足之处,请大家补充,欢迎在评论区交流。

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

我的博客原文:Javascript 地狱级的if else / switch case该如何优化?

往期回顾

 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?什么是点击劫持?如何防御

  • 67
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

富朝阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值