Если вы убьете слишком много if-else

JavaScript

Перед лицом слишком большого количества 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Для оптимизации; если оператор выполнения также сложен, когда условия могут быть модульными и нет требований к порядку, рекомендуется оптимизировать. Когда условия имеют строгие требования к последовательности и не требуют соблюдения правил, никакие изменения не рекомендуются.
  • Вложенные, если разделены на плиточные, если определить, как оптимизировать или не изменять

Обратите внимание на официальный аккаунт «Другой интерфейс», изучите интерфейс с другой точки зрения, быстро растем, играйте в новейшие технологии и исследуйте различные черные технологии вместе.