With too many if-else’s, the code might look redundant, or it might just be another “our project hundreds of thousands of ifs” diagram that gets forwarded around. However, through various design patterns and packaging, if is greatly reduced, but the readability may be slightly reduced and more abstract. So how do we choose
If there are too many if-else’s, the readability may be better or worse, and maintainability may be higher or lower; If there is less if-else, the code is highly abstract, the readability is low or constant, and the maintainability may or may not be high. There are probably a couple of things that could happen here
If tiling conditions are single
In this case, if streamlining is not streamlining, readability will not change, but the degree of streamlining is positively correlated with maintainability. Why is it that you can feel it just by looking at the code
Single execution statement
if (a === 1) {
console.log('this is 1')}else if (a === 2) {
console.log('this is 2')}else if (a === 3) {
console.log('this is 3')}/ /... There are many
else {
console.log('this is other')}Copy the code
Compact code:
// If a is from 1 to 10
console.log(`this is ${a > 0 && a < 10 ? a : 'other'}`)
// If a is from 1 to 5 and from 7-10
if ((a > 0 && a < 5) || (a > 7 && a < 10) {
console.log(`this is ${a}`)}else {
console.log('this is other')}// The value of a is flexible
const area = [[1.2], [5.7], [10.11]]
console.log(`${area.find(([from, to]) => {
return from <= a && a <= to
})? a : 'other'}`)
Copy the code
In this case, there’s no change in readability whether it’s condensed or not, but if it’s uncondensed, just write a bunch of ifs, and you can still see what’s going on. Maintainability is different. To add one or more numbers, you need to drill down to an IF branch and change them one by one. Maintainability is low. However, if streamlined, maintainability is greatly increased and the code is shorter. You just need to find if rules and encapsulate all the cases, and finally do “conditional driven”.
Some minimalism
There are some very simple, you can use &&, | |, three yuan
// before
if (cb) {
cb()
}
//after
cb && cb()
// before
if(! obj) { obj = {} } obj.a =1
//after
(obj || (obj = {})).a = 1
// before
if (type === true) {
value = 1
} else {
value = 2
}
//after
value = type ? 1 : 2
// before
if (type === DEL) {
this.delateData(id)
} else {
this.addData(id)
}
// after
this[type === DEL ? 'delateData' : 'addData'](id)
// or; (type === DEL ?this.delateData : this.addData)(id)
// before
if (a === 1 || a === 2 || a === 10) {
console.log('ok')}// after
if ([1.2.10].includes(a)) {
console.log('ok')}Copy the code
If the conditions are single and the execution statement is single, the recommended optimization index is ★★★★★
Complex execution statement
if (a === 1) {
console.log('this is 1')}else if (a === 2) {
console.log('this is the second')}else if (a === 3) {
console.log('this is three')}/ /... There are many
else {
console.log('this is other')}Copy the code
Compact code:
const map = {
1: 'this is 1'.2: 'this is the second'.3: 'this is three'./ /... A lot of
}
console.log(map[a] || 'this is other')
Copy the code
In this case, similar to executing a single statement, readability remains the same, but the code is less maintainable only slightly better. The usual solution is a k- V mapping. If you add a condition, you add another pair of k-v to the map.
This scenario is usually converted to switch. If the execution statement is very complex and irregular, the drawback of writing K-V is that a key is forced to correspond to a callback function, time is spent thinking about passing values, and the amount of code does not change, so optimization is not recommended
if (a === 1) {
console.log('this is 1')
alert(a * 100);
} else if (a === 2) {
console.log('this is the second')
document.body.innerHTML = a + 1 + b
}
// after
const map = {
1: (a) = > {
console.log('this is 1')
alert(a * 100);
},
2: (a, b) = > {
console.log('this is the second')
document.body.innerHTML = a + 1 + b
}
}
map[a](a, b) // The amount of code does not decrease or increase maintainability
Copy the code
The problem comes, what if the condition is single, but the processing statement is simple and complex? Case by case, categorize first and then divide the situation, and there will only be a few if and switch left
Summary: in the case of single condition and complex execution statement, it is suggested to optimize index: ★★★ when there is regularity, and ★ when there is no regularity
If tiling conditions are complex
If the condition is complex, single statement execution, then condition can use && and | | to simplify, three yuan, or flat out if – return, problem is solved. However, the conditions are complex and the probability of executing a statement is also complex.
if (a === 1) {
console.log(1);
} else if (arr.length === 3) {
alert('this is length 3 arr');
} else if (a === 2 && b === 1) {
console.log(2);
console.info('haha');
} else if (a === 2) {
console.log(222);
document.title = 'a = 2';
} else if (arr.length) {
console.error('arr is not empty');
}
Copy the code
There are no rules to follow, so there really is no further plan. However, if we observe that some conditions have intersection, such as a === x, we can extract this type of if:
const handleA = {
1: (a)= > {
console.log(1);
},
2: (a)= > {
if (b === 1) {
console.log(2);
console.info('haha');
} else {
console.log(222);
document.title = 'a = 2'; }}}const handleArrLen = {
3: (a)= > {
alert('this is length 3 arr'); }}if (handleA[a]) {
handleA[a]()
} else if (arr.length) {
;(handleArrLen[arr.length] || () = > {
console.log(222);
document.title = 'a = 2'; }}) ()Copy the code
This way, you can modularize your logic, increasing readability and maintainability, but sacrificing simplicity.
Notice that these conditions are modularized, which means that all conditions of the same class are grouped together. If the business logic has strict requirements on if conditions, for example, must be judged firsta === 1
, then atarr.length === 3
And then look ata === 2 && b === 1
In that order, it can’t be done
If () {if () {if () {if ();
if (a === 1) {
f1()
} else if (arr.length === 3) {
f2()
} else if (a === 2 && b === 1) {
f3()
} else if (a === 2) {
f4()
} else if (arr.length) {
f5()
}
Copy the code
In this case (the precondition is not often changed here, if it is often changed, will still vomit blood), the reduction of if is not bad:
const index = [a === 1, arr.length === 3, a === 2 && b === 1, a === 2, arr.length].findIndex(Boolean)
if(index ! = =- 1) {
[f1, f2, f3, f4, f5][index]()
}
Copy the code
If all else ifs are mutually exclusive and have no intersection, then if-return is better
if (a) {
// do xx about a
return
}
if (b) {
// do xx about b
return
}
Copy the code
Summary: if the conditions are complex and the execution statement is single, the optimization index is suggested: ★★★★; If the execution statement is also complex and conditions can be modularized without order requirements, optimization index is recommended: ★★★★ ★. When conditions are strictly sequential and irregular, it is not recommended to forcibly reduce if-else
If conditions are nested
Nesting is actually an enhancement of tiling, tiling nesting tiling, we can regard as multiple if tiling conditions complex case. For example, with the following code, let’s look for some patterns to optimize
if (id === 1) {
console.log(1);
if (type === 2) {
console.log('type2');
} else {
console.log('type3'); }}else if (id === 2) {
console.log(2);
if (type === 3) {
console.log('id2 type3');
if (ext === 1) {
console.log('ext1'); }}}else {
console.log('other id');
}
Copy the code
Partitioning by ID: The readability of other factors is sacrificed, but the maintainability of ids is enhanced
const handleId = {
1: (a)= > {
console.log(1)
console.log(type === 2 ? 'type2' : 'type3')},2: (a)= > {
console.log(2)
// The recommended optimization index is ★★, which may be unreadable, so keep the status quo
// when esLint is turned on, this will be cool and you must write back to normal if-else
type === 3 && (console.log('id2 type3'), ext === 1) && console.log('ext1')
}
}
handleId[type] ? handleId[type]() : console.log('other id')
Copy the code
If you break it down by type, it becomes much harder, and that’s the refactoring everyone fears. If the business logic behind it is indeed Type-dominated, it is only a matter of time before refactoring occurs. Therefore, the early design and product logic will determine whether the maintenance is comfortable or not
Summary: If condition has nesting condition, split if, in fact, is tiled if nested tiling if, if there is a rule to follow, then according to the previous tiling to reduce if. If there is no regularity or logical focus, then reducing if is not recommended
conclusion
- Simple conditions, single execution statement, strongly recommended to reduce
if-else
To optimize, using conditions to drive results (&& | |
Three or write your own logic) - The condition is simple and the execution statement is complex. You can keep the status quo or switch to the switch. If it is not complex, you can use map mapping
- Complex conditions, single execution statement, strongly recommended to reduce
if-else
To optimize; If the execution statement is also complex, comparison is recommended for optimization when conditions can be modularized and have no sequential requirements. When conditions are strictly sequential and irregular, no changes are recommended - Nested if, split into tiled if to determine how to optimize or not change
Pay attention to the public account “Different front-end”, learn front-end from a different perspective, grow fast, play with the latest technology, explore all kinds of black technology