JavaScript 条件语句中善用 return 让代码更清晰

笔记哥 / 05-27 / 2点赞 / 0评论 / 691阅读
## 条件语句 JS 的条件语句不太多,就 `if` 和 `switch` 两个,不过他们的使用方式也可以算是眼花缭乱了。 ### if 语句 if 字面意思:如果 xxx。程序中的用法也是这样,如果条件为真,则执行执行代码块,反之则不执行。 语法: ```js if (条件) { // 条件为真时执行 } else if (其他条件) { // 前一个条件为假且当前条件为真时执行 } else if (其他条件) { // 前面所有条件为假且当前条件为真时执行 } else { // 所有条件均为假时执行 } ``` 基础用法: ```js if (true) { console.log('条件为真执行代码块'); } // 如果代码块中只有一个语句,可以省略花括号 if (true) console.log('条件为真执行代码块'); ``` if & else 用法: ```js const age = 20; if (age < 18) { console.log('未成年'); } else { console.log('成年人'); } // 也可省略花括号 if (age < 18) console.log('未成年'); else console.log('成年人'); ``` 完整示例: ```js const age = 20; if (age < 18) { console.log('未成年'); } else if (age >= 18 && age < 50) { console.log('成年人'); } else if (age >= 50 && age < 65) { console.log('中年人'); } else { console.log('老年人'); } ``` 虽然 `if` 条件语句的语法上支持省略花括号,但在实际编码中,还是**不太建议**这么做,代码可读性降低,导致维护成本增加。 ### switch 语句 switch 语句和 if 语句很像,都用于条件判断,但 switch 语句中不支持条件表达式,case 后面只能是一个值或者运算表达式。 使用时特别注意 `break` 关键字,如果少了这个,您的代码会出大篓子。 使用 switch 语句: ```js const fruit = 'apple'; switch (fruit) { case 'apple': console.log('苹果'); break; case 'banana': console.log('香蕉'); break; case 'orange': console.log('橘子'); break; default: console.log('其他水果'); break; } ``` 以下代码**错误**写法,将始终都是 `default` 分支: ```js const age = 20; switch (age) { case age < 18: console.log('未成年'); break; case age >= 18 && age < 50: console.log('成年人'); break; case age >= 50 && age < 65: console.log('中年人'); break; default: console.log('老年人'); } ``` 但可以这样用: ```js const fruit = 'apple'; const apple = 'apple'; switch (fruit) { case apple: // 可以使用变量 console.log('苹果'); if (true) { // case 中可以使用条件语句 console.log('进入条件语句'); } break; case 'ban' + 'ana': // 可以使用运算符 console.log('香蕉'); break; default: console.log('其他水果'); break; } ``` 使用 switch 语句时,如果少了 `break` 关键字,就触发了神奇的 `case 穿透` 问题。看例子: ```js const fruit = 'apple'; switch (fruit) { case 'apple': console.log('苹果'); // 没有 break,代码会走到下一个 case case 'banana': console.log('香蕉'); // 依然没有 break,继续往下走 case 'orange': console.log('橘子'); // 仍然没有 break,继续 default: console.log('其他水果'); // switch 结束了 } ``` 以上代码会同时输出: ```bash 苹果 香蕉 橘子 其他水果 ``` ## if 优化 代码中免不了会出现很多 if 判断情况,如果代码组织能力太差,那就像捅了 if 窝一样~~ 看一个在曾经项目中前辈写的代码: ```js if (score.length != 0) { if (score >= 0 && score <= 10) { if (res1.status === '1') { if (res2.status === '1') {} if (viewShow) { } else {} } else {} } else {} } else {} ``` 这样的代码看起来舒服吗?反正我不舒服,真的太丑了,一层层的嵌套,像是走到逻辑地狱一样!! ### 使用卫语句优化 善用 return 优化 if 语句,提前处理异常或简单条件,减少嵌套层级。 优化前的代码: ```js function checkOrder(order) { if (order.isValid) { if (order.items.length > 0) { if (order.total > 0) { // 核心逻辑 return '1'; } else { return '2'; } } else { return '3'; } } else { return '4'; } } ``` 卫语句优化后: ```js function checkOrder(order) { if (!order.isValid) { return '4'; } if (order.items.length === 0) { return '3'; } if (order.total <= 0) { return '2'; } return '1'; } ``` ### 使用策略模式优化 `策略模式` 属于设计模式中的一种,通往超神路上,设计模式可以算是一道拦路虎,好的设计模式可以写出更优雅的代码。 在 JS 这个语言中,使用对象可以轻松的实现策略模式,优化不必要的 if 语句。 优化前的代码: ```js function getUserType(type) { if (type === 'A') { return '前端'; } else if (type === 'B') { return '后端'; } else if (type === 'C') { return '全干'; } else { return '未知'; } } ``` 优化后: ```js const userMap = { A: '前端', B: '后端', C: '全干', D: '未知', }; function getUserType(type) { return userMap[type] ?? userMap.default; } ``` ### 使用面向对象设计中的多态 将不同条件分支封装到不同类中,善用对象的多态概念,可以优化一部分代码。 说实话,JS 的代码还是不太习惯面向对象风格,还是习惯函数式编程,但这种优化方式还是值得学习的。 优化前的代码: ```js // 重构前(if-else 判断角色权限) function checkPermission(user) { if (user.role === 'admin') { return true; // 管理员有用所有操作权限 } else if (user.role === 'editor') { return action === 'edit'; // 网站编辑只有编辑权限 } else { return action === 'view'; // 访客只有查看权限 } } ``` 优化后: ```js // 重构后(多态实现) class Admin { // 管理员有用所有操作权限 can(action) { return true; } } class Editor { // 网站编辑只有编辑权限 can(action) { return action === 'edit'; } } class Guest { // 访客只有查看权限 can(action) { return action === 'view'; } } function checkPermission(user, action) { return user.can(action); } ``` ### 使用链式判断 利用 ES6 现代语法简化嵌套属性访问和条件判断,ES6 的可选链操作符是真的可以省下很多代码量,再组合使用空值合并,代码逼格瞬间提升。 优化前的代码: ```js function getUserCity(user) { if (user && user.address && user.address.location) { return user.address.location.city; } return '未知'; } ``` 优化后: ```js // 链式判断 + 空值合并 function getUserCity(user) { return user?.address?.location?.city ?? '未知'; } ``` ### 善用单一职责 将复杂条件拆分为多个独立函数,每个函数只做一件事,代码不要写得太复杂,谁都能看懂的代码才是好代码! 优化前的代码: ```js // 不同的用户价格计算逻辑 function calcPrice(user, product) { if (user.isVIP) { if (product.stock > 0) { return product.price * 0.8; // VIP 用户打8折 } else { throw new Error('缺货'); } } else { if (product.stock > 0) { return product.price; // 非 VIP 用户原价 } else { throw new Error('缺货'); } } } ``` 优化后: ```js function isProductAvailable(product) { // 判断产品是否有库存 if (product.stock <= 0) throw new Error('缺货'); } function getVIPDiscount(user) { return user.isVIP ? 0.8 : 1; // 判断用户是否打折 } function calcPrice(user, product) { isProductAvailable(product); // 先判断产品库存 return product.price * getVIPDiscount(user); // 计算价格 } ``` ## 写在最后 代码谁都能写,但写出来的代码好不好看,能不能维护,这就是考验技术的时候了。 总结几个编码原则,仅供参考: 1、单一职责:每个函数/模块只处理一个逻辑。 2、早返早拒:优先处理无效条件,减少嵌套。 3、数据结构化:用对象、Map 或类替代硬编码条件。 4、现代语法:善用 ?.、??、||、&& 等简化代码。