目录
问题
一、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?什么是点击劫持?如何防御