Перед лицом слишком большого количества if-else код может выглядеть избыточным, или это может быть изображение «сотни и тысячи строк if в нашем проекте», которое было отправлено повсюду. Но после различных паттернов проектирования и инкапсуляции, if сильно уменьшается, но читабельность может немного снижаться, да и более абстрактно. Итак, как мы должны выбирать?
Помимо других факторов, если слишком много if-else, читабельность может быть лучше или хуже, а ремонтопригодность также выше или ниже; если if-else слишком мало, код будет очень абстрактным, и читабельность ухудшится. быть ниже или без изменений, ремонтопригодность может быть высокой или низкой. Может быть несколько ситуаций
если условие плитки одиночное
В этом случае, если упрощение не является упрощением, удобочитаемость не изменится, но степень упрощения и ремонтопригодности положительно коррелируют. Почему, вы можете почувствовать это, взглянув на код.
один оператор выполнения
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')
}
// ...还有很多
else {
console.log('this is other')
}
Сжатый код:
// 如果上面的if a是从1到10
console.log(`this is ${a > 0 && a < 10 ? a : 'other'}`)
// 如果上面的if a是从1到5和从7-10
if ((a > 0 && a < 5) || (a > 7 && a < 10) {
console.log(`this is ${a}`)
} else {
console.log('this is other')
}
// a取值灵活区间
const area = [[1,2], [5,7], [10, 11]]
console.log(`${area.find(([from, to]) => {
return from <= a && a <= to
}) ? a : 'other'}`)
При этом, упрощен он или нет, читабельность не изменилась.Если не упрощен, напишите кучу if, и все равно легко видно, что он делает. Ремонтопригодность отличается.Если вы хотите добавить один или несколько номеров, вам нужно углубиться в определенную ветку if и изменить ее по одному, что имеет низкую ремонтопригодность. Однако, если его упростить, значительно повышается ремонтопригодность, а также получается короткий код. Просто найдите правила if и инкапсулируйте все случаи и, наконец, добейтесь «управляемого условиями»
некоторые минималистские ситуации
Есть несколько очень простых случаев, когда вы можете использовать&&
,||
, тройной раствор
// 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')
}
В случае одного условия и одного оператора выполнения рекомендуется оптимизировать индекс: ★★★★★
сложное выполнение оператора
if (a === 1) {
console.log('this is 1')
} else if (a === 2) {
console.log('this is 二')
} else if (a === 3) {
console.log('this is three')
}
// ...还有很多
else {
console.log('this is other')
}
Сжатый код:
const map = {
1: 'this is 1',
2: 'this is 二',
3: 'this is three',
// ...很多
}
console.log(map[a] || 'this is other')
В этом случае, аналогично выполнению одного оператора, читабельность остается неизменной, а код сокращается.Ремонтопригодность лишь немного лучше. Обычное решение - отображение k-v. Добавляем условие, просто добавляем на карту пару k-v (т.к. обработка условия сложная, в условии нет места для оптимизации, его надо писать)
В этом сценарии должно быть более распространено переключение на переключатель. Если оператор выполнения сложный и нерегулярный, наступит дефект написания kv: клавиша вынуждена соответствовать callback-функции, а рассмотрение проблемы передачи значения займет время, а объем кода не изменился, поэтому в настоящее время оптимизация не рекомендуется.
if (a === 1) {
console.log('this is 1')
alert(a * 100);
} else if (a === 2) {
console.log('this is 二')
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 二')
document.body.innerHTML = a + 1 + b
}
}
map[a](a, b) // 代码量并没有减少也没有增强维护性
Вопрос в том, что условие единичное, а если оператор обработки простой или сложный? в каждом конкретном случае сначала классифицируйте, а затем разделите случай, в конце останется только небольшое количество if и switch
Резюме: В случае одного условия и сложных операторов выполнения рекомендуется оптимизировать индекс, когда есть правило: ★★★, а когда оно нерегулярно, рекомендуемый индекс: ★
если условия тайлинга сложные
Если условие сложное, а оператор выполнения один, то условие можно передать&&
,||
, тернарный для упрощения или мозаичныйif-return
, проблема решена. Однако условия сложны, и вероятность выполнения оператора также сложна.
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');
}
Нет никаких правил, которым нужно следовать, поэтому на самом деле нет никакого дальнейшего плана. Но мы наблюдаем и обнаруживаем, что некоторые условия пересекаются, напримерa === x
, мы можем извлечь этот тип, если:
const handleA = {
1: () => {
console.log(1);
},
2: () => {
if (b === 1) {
console.log(2);
console.info('haha');
} else {
console.log(222);
document.title = 'a = 2';
}
}
}
const handleArrLen = {
3: () => {
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';
})()
}
Таким образом, логика может быть модульной для повышения удобочитаемости и удобства сопровождения, но за счет простоты.
Обратите внимание, что приведенные выше подусловия имеют модульную структуру, что означает, что условия одного типа группируются вместе. Например, если бизнес-логика предъявляет строгие требования к условию if, оно должно оцениваться в первую очередь.a === 1
, посмотри сноваarr.length === 3
, посмотри сноваa === 2 && b === 1
, в таком порядке, то это не может быть сделано
Также есть случай, когда инкапсулированная функция вызывается прямо в 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()
}
В этом случае (необходимо условие, что вы не будете часто менять, если вы будете часто менять, вас все равно будет рвать кровью) неплохо уменьшить, если:
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]()
}
Если все остальные if являются взаимоисключающими и не имеют пересечения, замените на
if-return
лучше
if (a) {
// do xx about a
return
}
if (b) {
// do xx about b
return
}
Резюме: если условие сложное, а оператор выполнения один, рекомендуется оптимизировать индекс: ★★★★★; если оператор выполнения также сложный, когда условие может быть модульным и нет требования последовательности, индекс рекомендуемый индекс оптимизации: ★★★★. Когда условия имеют строгие требования последовательности и нет правил, которым нужно следовать, не рекомендуется принудительно уменьшать if-else.
если условия вложены
Вложенность на самом деле является усовершенствованием тайлинга, тайлинг вложенного тайлинга, мы можем рассматривать его какНесколько, если условия мозаики сложныеситуация. Например, есть следующий код, ищем какие-то правила для его оптимизации
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');
}
Разделение на id: читабельность других факторов приносится в жертву, но повышается удобство сопровождения id
const handleId = {
1: () => {
console.log(1)
console.log(type === 2 ? 'type2' : 'type3')
},
2: () => {
console.log(2)
// 这里建议优化指数为★★,可能可读性低,所以保持现状也行
// eslint一开,这套凉凉,必须写回普通if-else
type === 3 && (console.log('id2 type3'), ext === 1) && console.log('ext1')
}
}
handleId[type] ? handleId[type]() : console.log('other id')
Если в это время его разделить по типам, то сложность сильно возрастает, а это реконструкция, которой все боятся. Если в последней бизнес-логике действительно доминирует тип, то рефакторинг — вопрос времени. Следовательно, ранний дизайн и логика продукта будут определять, будет ли последующее обслуживание удобным или нет.
Резюме: если условия вложены, разделить, если на самом деле это плитка, если вложенные плитки, если есть правила, которым нужно следовать, то уменьшить, если в соответствии с предыдущей плиткой. Если правил нет, и это не фокус логики, то уменьшать не рекомендуется, если
Суммировать
- Условие простое, оператор выполнения один, и настоятельно рекомендуется уменьшить
if-else
оптимизировать, используя условия для достижения результатов (&& ||
Тернарный или напишите свою небольшую логику) - Условие простое, оператор выполнения сложный, можно сохранить статус-кво или заменить его переключателем, если не сложно, можно использовать отображение карты
- Условия являются сложными, оператор выполнения является одиноким, и настоятельно рекомендуется уменьшить
if-else
Для оптимизации; если оператор выполнения также сложен, когда условия могут быть модульными и нет требований к порядку, рекомендуется оптимизировать. Когда условия имеют строгие требования к последовательности и не требуют соблюдения правил, никакие изменения не рекомендуются. - Вложенные, если разделены на плиточные, если определить, как оптимизировать или не изменять
Обратите внимание на официальный аккаунт «Другой интерфейс», изучите интерфейс с другой точки зрения, быстро растем, играйте в новейшие технологии и исследуйте различные черные технологии вместе.