모든 사람이 대규모 if else
가 포함된 프로젝트 코드를 접한 적이 있을 것입니다. 여러 개의 중첩된 if else
는 유지 관리 중에 가끔 버그 문제를 해결한 후에 정말 짜증스럽습니다. 심각하게 공허해진 느낌이 듭니다. if else
的项目代码吧,多重嵌套的 if else
在维护的时候真的让人很恼火,有时候一个 bug 排查下来,严重感觉身体被掏空。
本文并未有消灭或歧视 if else
的意思,if else
的好用都知道,这里只是在某些特定场景为大家额外提供一种思路,增加我们代码的可读性。
Javascript 的逻辑或 ||
的短路运算有时候可以用来代替一些比较简单的 if else
||
的短路运算:若左边能转成true,返回左边式子的值,反之返回右边式子的值。下面用一个简单的案例来表述
let c if(a){ c = a } else { c = b }
大家看着上面的代码会难受嘛(本人有一丢丢的强迫症),明明就是一个很简单的判断却需要写好几行代码才能实现。这个时候我们就可以用短路运算去简化我们的代码啦。
let c = a || b
这样看起来是不是就简洁了很多?。
三元运算符我觉得大家应该都很熟悉吧,很多时候简单的一些判断我们都可以使用三元运算符去替代 if else
,这里只推荐 一层 三元运算符,因为多层嵌套的三元运算符也不具备良好的可读性。
例子:条件为 true 时返回1,反之返回0:
const fn = (nBoolean) { if (nBoolean) { return 1 } else { return 0 } } // 使用三元运算符 const fn = (nBoolean) { return nBoolean ? 1 : 0 }
三元运算符使用的地方也比较多,比如:条件赋值,递归...
// num值在nBoolean为true时为10,否则为5 let num = nBoolean ? 10 : 5 // 求0-n之间的整数的和 let sum = 0; function add(n){ sum += n return n >= 2 ? add(n - 1) : result; }; let num = add(10);//55
上述的两种方式:短路运算跟三元运算虽然很好用,代码也很简洁,不过都只能用于简单的判断,遇到多重条件判断就不能使用了。
对于 switch case
,虽然它的可读性确实比 else if
更高,但是我想大家应该都觉得它写起来比较麻烦吧(反正我觉得很麻烦)。
例:有A、B、C、D四种种类型,在A、B的时候输出1,C输出2、D输出3,默认输出0。
let type = 'A' //if else if if (type === 'A' || type === 'B') { console.log(1); } else if (type === 'C') { console.log(2); } else if(type === 'D') { console.log(3); } else { console.log(0) } //switch case switch (type) { case 'A': case 'B': console.log(1) break case 'C': console.log(2) break case 'D': console.log(3); break; default: console.log(0) }
对象配置看起来跟 策略模式
差不多,都是根据不同得参数使用不同得数据/算法/函数。
策略模式就是将一系列算法封装起来,并使它们相互之间可以替换。被封装起来的算法具有独立性,外部不可改变其特性。
接下来我们用对象配置的方法实现一下上述的例子
let type = 'A' let tactics = { 'A': 1, 'B': 1, 'C': 2, 'D': 3, default: 0 } console.log(tactics[type]) // 1
接下来用几个例子让大家更加熟悉一点。
根据不同的用户使用不同的折扣,如:普通用户不打折,普通会员用户9折,年费会员8.5折,超级会员8折。
使用if else
实现
// 获取折扣 --- 使用if else const getDiscount = (userKey) => { if (userKey === '普通会员') { return 0.9 } else if (userKey === '年费会员') { return 0.85 } else if (userKey === '超级会员') { return 0.8 } else { return 1 } } console.log(getDiscount('普通会员')) // 0.9
使用对象配置/策略模式实现?
// 获取折扣 -- 使用对象配置/策略模式 const getDiscount = (userKey) => { // 我们可以根据用户类型来生成我们的折扣对象 let discounts = { '普通会员': 0.9, '年费会员': 0.85, '超级会员': 0.8, 'default': 1 } return discounts[userKey] || discounts['default'] } console.log(getDiscount('普通会员')) // 0.9
从上面的案列中可以明显看得出来,使用对象配置比使用if else可读性更高,后续如果需要添加用户折扣也只需要修改折扣对象就行。
对象配置不一定非要使用对象去管理我们键值对,还可以使用 Map
去管理?,如:
// 获取折扣 -- 使用对象配置/策略模式 const getDiscount = (userKey) => { // 我们可以根据用户类型来生成我们的折扣对象 let discounts = new Map([ ['普通会员', 0.9], ['年费会员', 0.85], ['超级会员', 0.8], ['default', 1] ]) return discounts.get(userKey) || discounts.get('default') } console.log(getDiscount('普通会员')) // 0.9
公司的年终奖根据员工的工资基数和绩效等级来发放的。例如,绩效为A的人年终奖有4倍工资,绩效为B的有3倍,绩效为C的只有2倍。
假如财务部要求我们提供一段代码来实现这个核算逻辑,我们要怎么实现呢?
这不是很简单嘛,一个函数就搞定了。
const calculateBonus = (performanceLevel, salary) => { if (performanceLevel === 'A'){ return salary * 4 } if (performanceLevel === 'B'){ return salary * 3 } if (performanceLevel === 'C'){ return salary * 2 } } calculateBonus( 'B', 20000 ) // 输出:60000
可以发现,这段代码十分简单,但是 calculateBonus
函数比较庞大,所有的逻辑分支都包含在if else
语句中,如果增加了一种新的绩效等级D,或者把A等级的倍数改成5,那我们必须阅读所有代码才能去做修改。
所以我们可以用对象配置/策略模式去简化这个函数
let strategies = new Map([ ['A', 4], ['B', 3], ['C', 2] ]) const calculateBonus = (performanceLevel, salary) => { return strategies.get(performanceLevel) * salary } calculateBonus( 'B', 20000 ) // 输出:60000
至此,这个需求做完了,然后产品经理说要加上一个部门区分,假设公司有两个部门D和F,D部门的业绩较好,所以年终奖翻1.2倍,F部门的业绩较差,年终奖打9折。
改造以上代码,把状态值拼接,然后存入Map中
// 以绩效_部门的方式拼接键值存入 let strategies = new Map([ ['A_D', 4 * 1.2], ['B_D', 3 * 1.2], ['C_D', 2 * 1.2], ['A_F', 4 * 0.9], ['B_F', 3 * 0.9], ['C_F', 2 * 0.9] ]) const calculateBonus = (performanceLevel, salary, department) => { return strategies.get(`${performanceLevel}_${department}`) * salary } calculateBonus( 'B', 20000, 'D' ) // 输出:72000
本文主要是向大家传递一种思想,我们有很多的方法去优化我们的代码,提高我们代码的可读性。
对if else
并没有歧视的意思,只是希望在大家以后的代码中不仅仅只有if else
if else
를 제거하거나 차별하려는 의도가 아닙니다. if else
의 유용성은 누구나 알고 있습니다. 몇 가지 특정 시나리오를 통해 코드의 가독성을 높일 수 있는 아이디어를 제공하세요.
||
의 단락 동작은 때때로 if else
||
의 상대적으로 간단한 단락 연산을 대체하는 데 사용됩니다. 왼쪽이 true로 변환될 수 있으면 반환 왼쪽 표현식의 값, 그렇지 않으면 오른쪽 방정식의 값을 반환합니다. if else
를 대체하는 연산자. 다중 수준 중첩 삼항 연산자는 가독성이 좋지 않으므로 여기서는 한 수준 삼항 연산자만 사용하는 것이 좋습니다. 🎜🎜예: 조건이 true이면 1을 반환하고, 그렇지 않으면 0을 반환합니다:🎜rrreee🎜삼항 연산자는 조건부 할당, 재귀...🎜rrreeeswitch case
의 경우, else if
보다 가독성은 확실히 높지만, 작성하는 것이 더 번거롭다고 다들 생각하시는 것 같아요(어쨌든 매우 번거롭다고 생각합니다). 🎜🎜예: A, B, C, D의 네 가지 유형이 있습니다. A와 B가 출력되면 1이 출력되고 C는 2, D는 3이 출력됩니다. 기본 출력은 0입니다. 🎜rrreee전략 모드
와 유사해 보이지만 둘 다 서로 다릅니다. 매개변수는 다른 데이터/알고리즘/함수를 사용합니다. 🎜🎜전략 패턴은 일련의 알고리즘을 캡슐화하여 상호 교환 가능하게 만듭니다. 캡슐화된 알고리즘은 독립적이며 그 특성은 외부 세계에 의해 변경될 수 없습니다. 🎜🎜다음에는 객체 구성 방법을 사용하여 위의 예를 구현해보겠습니다🎜rrreee🎜다음에는 모두가 더 친숙해질 수 있도록 몇 가지 예를 사용하겠습니다. 🎜if else
를 사용하여 구현🎜rrreee🎜객체 구성/전략 패턴을 사용하여 구현하시겠습니까?🎜rrreee🎜위의 경우에서 if else If를 사용하는 것보다 객체 구성을 사용하는 것이 더 읽기 쉽다는 것이 분명합니다. 나중에 사용자 할인을 추가해야 하며 할인 개체만 수정하면 됩니다. 🎜🎜객체 구성에서는 키-값 쌍을 관리하기 위해 반드시 객체를 사용할 필요는 없습니다. 또한 Map
을 사용하여 관리할 수도 있습니다. 예: 🎜rrreeecalculateBonus
함수가 상대적으로 크다는 것을 알 수 있습니다. 모든 논리적 분기는 새로운 If 문에 포함됩니다. 성능 등급이 D이거나 등급 A의 배수가 5로 변경되면 수정하기 전에 모든 코드를 읽어야 합니다. 🎜🎜그래서 객체 구성/전략 패턴을 사용하여 이 기능을 단순화할 수 있습니다🎜rrreee🎜이 시점에서 이 요구 사항이 완료되었으며 제품 관리자는 부서 구분을 추가해야 한다고 말했습니다. 회사에 두 개의 부서가 있다고 가정합니다. F부서의 성과가 상대적으로 부진하여 연말 상여금을 10% 할인해 줍니다. 🎜🎜위 코드를 변환하고, 상태 값을 이어붙인 후 Map🎜rrreeeif else
를 차별하려는 것이 아닙니다. 단지 향후 코드에 if else
이상의 기능이 있기를 바랍니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오🎜를 방문하세요! ! 🎜