Есть два и есть два, есть два и три. Превратите неизвестное в известное и станьте своим собственным знанием
предисловие
Давным-давно я опубликовал статью:[Анализ] Схемы замены if-else и переключения в конкретных сценариях, но сценариев использования if-else не так уж и мало как вышеперечисленных статей, сценариев много, и сегодня я напишу, что можно заменить или оптимизировать в разработкеif-else
место действия.
Акцент на замену или оптимизацию здесь
if-else
, осуществляется по определенному сценарию. Цель состоит в том, чтобы улучшить код в конкретных сценариях и сделать его кратким. Повышение удобочитаемости, ремонтопригодности и возможности повторного использования кода. еслиif-else
Используемые сценарии относительно просты или оптимизированы.if-else
Тогда это плохо скажется на коде. Не рекомендуется использовать другие решения для замены или оптимизации, не писатьif-else
Не написав, вы не сможете оптимизировать ради оптимизации.
1. Запрос диапазона
Например, нарисуйте диапазон выигрышных номеров, диапазон выигрышных номеров 9-12, 14-18, а затем вам нужно определить, выиграл ли номер в лотерею, логика очень проста для достижения
let num1= 15
let num2= 13
if((num1>=9 && num1<=12)||(num1>=14 && num1<=18)){
// 中奖了
}
if((num2>=9 && num2<=12)||(num2>=14 && num2<=18)){
// 中奖了
}
Это вроде бы не проблема записать, если в будущем спрос изменится, выигрышное число будет не 9-12 или 14-18. Скорее 10-14 или 18-20. Это изменит исходную логику кода
if((num1>=10 && num1<=14)||(num1>=18 && num1<=20)){
// 中奖了
}
Или есть другие требования, например, выигрышный номер 9-12, 14-18, 20-22 или 26-30. Все равно придется менять логику if-else
if((num1>=9 && num1<=12)||(num1>=14 && num<=18)||(num1>=20 && num1<=22)||(num2>=26 && num1<=30)){
// 数字在范围内
}
Теперь вы можете использовать некоторые для инкапсуляции функции, вам нужно инкапсулировать ее только один раз, и если объем будущих требований изменится, вы можете
function handleCheckRange(num, ...ranges){
return ranges.some(item=>num>=item[0]&&num<=item[1])
}
handleCheckRange(num1,[9,12],[14,18]) //true
handleCheckRange(num2,[9,12],[14,18]) //false
handleCheckRange(num2,[10,14],[18,20]) //true
handleCheckRange(num2,[9,12],[14,18],[20,22],[26,30]) //false
1. Некоторые люди могут подумать, что если есть другое требование, условие суждения не >= или , или =? так
handleCheckRange
Его также необходимо изменить. В этом случае необходимо изменить этот метод при возникновении других условий суждения. Но изменить этот метод несложно, просто инкапсулируйте его напрямую2. Если в условиях оценки слишком много изменений, метод инкапсуляции должен быть совместим с другими условиями оценки.Вы можете обратиться к моим примечаниям:Упражнение 5. Моделирование реализации открытых и закрытых интервалов, здесь обсуждаться не будет.
2. Множественные и условия
Я считаю, что каждый столкнется с проблемами, которые могут иметь комбинацию нескольких состояний.
Например, если есть бонусные баллы за участие в горячих распродажах, статус активности (status
), предварительный нагрев (status=1
),в ходе выполнения(status=2
). тип пользователя(type
) также делится на обычных пользователей (type=1
) вип пользователь (type=2
)
Правила таковы: 1. Участвуйте в активности во время разминки, VIP-пользователи получат 1000 баллов, а обычные пользователи — 700 баллов. 1. Участвуйте в текущей активности, VIP-пользователи получат 800 баллов, а обычные пользователи — 300 баллов.
Это было написано раньше
let status=1
let type=2
if(status===1){
if(type===1){
console.log('普通用户在预售中参与活动,赠送700积分')
}
else if(type===2){
console.log('vip用户在预售中参与活动,赠送1000积分')
}
}
else if(status===2){
if(type===1){
console.log('普通用户在进行中参与活动,赠送300积分')
}
else if(type===2){
console.log('vip用户在进行中参与活动,赠送800积分')
}
}
// 或者
if(status===1&&type===1){
console.log('普通用户在预售中参与活动,赠送700积分')
}
else if(status===1&&type===2){
console.log('vip用户在预售中参与活动,赠送1000积分')
}
else if(status===2&&type===1){
console.log('普通用户在进行中参与活动,赠送300积分')
}
else if(status===2&&type===2){
console.log('vip用户在进行中参与活动,赠送800积分')
}
Но теперь вы можете использовать метод записи obj, так что, если у вас возникнут какие-либо условия для изменения в будущем, просто измените конфигурацию obj напрямую.
let obj={
'status=1&type=1':'普通用户在预售中参与活动,赠送700积分',
'status=1&type=2':'vip用户在预售中参与活动,赠送1000积分',
'status=2&type=1':'普通用户在进行中参与活动,赠送300积分',
'status=2&type=2':'普通用户在进行中参与活动,赠送800积分'
}
console.log(obj[`status=${status}&type=${type}`])
3. Множественное или условие
Например, введите название города и выведите название провинции.
let city='广州'
if(city==='广州'||city==='佛山'){
console.log('广东')
}
else if(city==='海口'||city==='三亚'){
console.log('海南')
}
Недостатком этого является то, что еслиif-else
По мере увеличения числа код будет увеличиваться, а условия оценки станут очень длинными.Еще одна проблема заключается в том, что стиль может быть неоднородным.
Оптимизируйте другими способами метод первый
let arr=[
{
city:'广州',
province:'广东'
},
{
city:'佛山',
province:'广东'
},
{
city:'海口',
province:'海南'
},
{
city:'三亚',
province:'海南'
}
]
console.log(arr.filter(item=>item.city===city)[0].province)//广东
Способ второй
let city='广州'
let obj={
'广州':'广东',
'佛山':'广东',
'海口':'海南',
'三亚':'海南',
}
console.log(obj[city])// 广东
Увидев, что Гуандун и Хайнань были написаны так много раз, каждый может быть подавлен.В провинции 20 городов, и их нужно написать 20 раз.Некоторые люди могут думать о городах как о городах.key
, а затем оценивать входящиеcity
Вы вkey
Внутри код выглядит следующим образом.
let city='广州'
let obj={
'广州,佛山':'广东',
'海口,三亚':'海南',
}
for(let key in obj){
if(key.includes(city)){
console.log(obj[key])
break
}
}
//广东
Но вылезают и недостатки, т. е. вышеописанный способ имеетbug
, выводится только одно слово названия города, а также может быть выведена соответствующая провинция.
let city='州'
let obj={
'广州,佛山':'广东',
'海口,三亚':'海南',
}
for(let key in obj){
if(key.includes(city)){
console.log(obj[key])
break
}
}
//广东
Чтобы решить эту проблему, есть два пути, один из которых состоит в том, чтобы поставитьkey
Преобразуйте в массив, а затем оцените или используйтеMap
// 方式一:把 key 转成数组再判断
let city='广州'
let obj={
'广州,佛山':'广东',
'海口,三亚':'海南',
}
let keys=[]
for(let key in obj){
keys=key.split(',')
if(keys.includes(city)){
console.log(obj[key])
break
}
}
// 方式二:使用Map
let city='广州'
let map=new Map([
[['广州','佛山'],'广东'],
[['海口','三亚'],'海南'],
])
for (let key of map.keys()) {
if(key.includes(city)){
console.log(obj[key])
break
}
}
//广东
4. Неправильное если-иначе, если
В этом случаеif-elseif
Правил не найти. Например, необходимо проводить мероприятия по отбору студентов на получение стипендии.
1. Комплексная оценка качества учащихся (quality>=90
) 90 или выше, со средним баллом 4,5 или выше, чтобы стать первоклассным кандидатом на получение стипендии.
2. Учащиеся с общим баллом качества 80 или выше (quality>=80
), со средним баллом не менее 2,5 по каждому предмету, чтобы стать кандидатом на получение стипендии второго класса.
3. Общий балл качества обучающихся должен быть не ниже 75 (quality>=75
), получил другие награды и награды и стал кандидатом на получение стипендии третьего класса.
let studentInfo={
name:'守候',
chinese:4.6,
math:4.7,
english:4,
computer:4.8,
quality:93,
prizes:['搬砖','扫地']
}
let subjectAll=['chinese','math','english','computer']
function handle (student,subject) {
function getAverage(){
let sum=0
subject.forEach(item=>sum+=student[item])
return sum/subject.length
}
function checkScore(){
return subject.every(item => student[item]>2.5)
}
if(student.quality>=90&&getAverage()>4.5){
console.log('成为一等奖学金候选人')
// 其他代码
}
else if(student.quality>=80&&checkScore()){
console.log('成为二等奖学金候选人')
// 其他代码
}
else if(student.quality>=75&&student.prizes.length>0){
console.log('成为三等奖学金候选人')
// 其他代码
}
}
handle(studentInfo,subjectAll) //成为一等奖学金候选人
Код выглядит очень простым и завершенным, но в реальной разработкеif-elseif
количество уровней, каждыйif-elseif
Логика суждения и код, выполняющий внутри нее операцию, выходят далеко за рамки этого примера. Такhandle
Код для этого метода будет длинным, а сам метод станет огромным. Это сильно влияет на удобочитаемость, ремонтопригодность и возможность повторного использования кода. Если требования меняются, необходимо уточнить логику всей функции.
Приведенный выше код в основном нуждается в обработкеif-elseif
. но этиif-else
Нет правил, которые можно найти, поэтому все можно извлечь только по отдельности, и все они инкапсулированы в функции.
function handle (student,subject) {
function getAverage(){
let sum=0
subject.forEach(item=>sum+=student[item])
return sum/subject.length
}
function checkScore(){
return subject.every(item => student[item]>2.5)
}
let rules=[
{
rule(){
return student.quality>=90&&getAverage()>4.5
},
fn(){
console.log('成为一等奖学金候选人')
// 其他代码
}
},
{
rule(){
return student.quality>=80&&checkScore()
},
fn(){
console.log('成为二等奖学金候选人')
// 其他代码
}
},
{
rule(){
return student.quality>=75&&student.prizes.length>0
},
fn(){
console.log('成为三等奖学金候选人')
// 其他代码
}
}
]
for(let item of rules){
if(item.rule()){
item.fn()
// 执行完函数马上返回,不再执行下一次循环
return
}
}
}
Это пока естьitem.fn()
Если он выполнен, значит, студент стал кандидатом, просто верните его.
Таким образом, код также полностью соответствует предыдущемуif-elseif
логика. У некоторых могут возникнуть сомнения, что код не уменьшился, а увеличился, но на самом деле этот код был разбит на куски, а читабельность и ремонтопригодность улучшены, если есть необходимость что-то там изменить, мы тоже не будем нужно возиться со всей функцией, просто изменитьrules
.
5. Несколько, если
В другом случае несколькоif-else
связанный с исполняемым кодом,
Например, есть страница, которая может отображать следы, записанные пользователем, а также позволяет пользователю выбрать запись собственных следов.Областью записи может быть провинция, город или район. Затем код должен реализовать провинцию и город, связь с несколькими вариантами выбора. Логика такова: если вы выбираете провинцию, вы можете не выбирать город, но если вы выбираете город, вы выбираете провинцию и так далее. Ниже приведен простой псевдокод.
function initPostion(){
//所有省份列表
let provinceList=['广东','广西','海南','....']
//已选省份下辖的所有城市
let cityList=[]
//已选城市下辖的所有区
let districtList=[]
//已选择省份
let selectedProvinces=['广东','广西']
//已选择城市
let selectedCitys=['广州']
//已选择区
let selectedDistricts=['天河区']
//如果选了省份
if (selectedProvinces.length>0) {
//根据 selectedProvinces 获取 cityList 的逻辑
//其他代码
}
if (selectedCitys.length>0) {
//根据 selectedCitys 获取 districtList 的逻辑
//其他代码
}
//其他初始化显示的逻辑
}
Как только псевдокод написан, некоторые разработчики должны были увидеть проблему. всеif
Все они связаны друг с другом, и логика кода в if может быть намного длиннее. Если в дальнейшем спрос изменится, требуется выбрать страну, затем провинцию или город, либо после выбора района можно также выбрать город и деревню. К тому времениif
станет больше,initPostion
Общий код может стать огромным. Обслуживание может быть трудоемким и подверженным ошибкам.
Чтобы решить эту проблему, вы можетеif
разделить на функции
function initPostion(){
//所有省份列表
let provinceList=['广东','广西','海南','....']
//已选省份下辖的所有城市
let cityList=[]
//已选城市下辖的所有区
let districtList=[]
//已选择省份
let selectedProvinces=['广东','广西']
//已选择城市
let selectedCitys=['广州']
//已选择区
let selectedDistricts=['天河区']
let handleObj={
provinces(){
//如果选了省份
if (selectedProvinces.length>0) {
//根据 selectedProvinces 获取 cityList 的逻辑
//其他代码
}
},
city(){
if (selectedCitys.length>0) {
//根据 selectedCitys 获取 districtList 的逻辑
//其他代码
}
}
}
let handleFns=['provinces','city']
for(let fnName of handleFns){
handleObj[fnName]()
}
//其他初始化显示的逻辑
}
Может показаться, что кода много, но управлять им будет проще, чем исходным решением.if
Все они разбиты на функции, если вам нужно изменить определенный фрагмент кода, просто измените определенный фрагмент кода, и вам не нужно менять другие коды. Если есть изменение в спросе, это должно изменитьсяhandleObj
функция свойства , иhandleFns
порядок .
Ссылка на ссылку
[Анализ] Схемы замены if-else и переключения в конкретных сценариях
Более элегантный способ написания сложных суждений в JavaScript
резюме
хорошо, оif-else
На этом вторая статья о замене и оптимизации схемы . Здесь снова заменить и оптимизироватьif-else
Заявление, рекомендуется использовать конкретную схему в конкретном сценарии. Помните, что нельзя заменять ради замены, не оптимизировать ради оптимизации.
Если я найду другой выигрыш в будущем, я напишу статью как можно скорее. Если у всех есть какие-либо предложения, мнения или ошибки в статье, пожалуйста, оставьте сообщение в области комментариев для улучшения.
------------------------- Великолепная разделительная линия --------------------
Если вы хотите узнать больше и пообщаться со мной, добавьте меня в WeChat. Или обратите внимание на мой паблик WeChat: В ожидании книжного магазина