помещение
Когда мы пишем js-код, мы часто сталкиваемся со сложными логическими суждениями.Обычно вы можете использовать if/else или switch для реализации нескольких условных суждений, но возникает проблема.По мере увеличения сложности логики, if/Else/switch становится все более и более раздутым и непонятным, поэтому, как написать логику суждения более элегантно, эта статья поможет вам попробовать.
Например
Посмотрите на кусок кода
/**
* 按钮点击事件
* @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
*/
const onButtonClick = (status)=>{
if(status == 1){
sendLog('processing')
jumpTo('IndexPage')
}else if(status == 2){
sendLog('fail')
jumpTo('FailPage')
}else if(status == 3){
sendLog('fail')
jumpTo('FailPage')
}else if(status == 4){
sendLog('success')
jumpTo('SuccessPage')
}else if(status == 5){
sendLog('cancel')
jumpTo('CancelPage')
}else {
sendLog('other')
jumpTo('Index')
}
}
Код можно увидеть, нажав кнопку логики: сделать две вещи, в зависимости от активного состояния, отправить логи в закопанную точку и перейти на соответствующую страницу, вы можете легко переписать предложенную схему этого кода, переключать представления:
/**
* 按钮点击事件
* @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
*/
const onButtonClick = (status)=>{
switch (status){
case 1:
sendLog('processing')
jumpTo('IndexPage')
break
case 2:
case 3:
sendLog('fail')
jumpTo('FailPage')
break
case 4:
sendLog('success')
jumpTo('SuccessPage')
break
case 5:
sendLog('cancel')
jumpTo('CancelPage')
break
default:
sendLog('other')
jumpTo('Index')
break
}
}
Что ж, это выглядит намного нагляднее, чем if/else.Внимательные студенты также обнаружили небольшую хитрость.Когда логика случая 2 и случая 3 одинакова, оператор выполнения и break можно опустить, а случай случая 2 будет автоматически выполнен. выполнить случай случая 3. логика.
В это время некоторые учащиеся скажут, что есть более простой способ записи:
const actions = {
'1': ['processing','IndexPage'],
'2': ['fail','FailPage'],
'3': ['fail','FailPage'],
'4': ['success','SuccessPage'],
'5': ['cancel','CancelPage'],
'default': ['other','Index'],
}
/**
* 按钮点击事件
* @param {number} status 活动状态:1开团进行中 2开团失败 3 商品售罄 4 开团成功 5 系统取消
*/
const onButtonClick = (status)=>{
let action = actions[status] || actions['default'],
logName = action[0],
pageName = action[1]
sendLog(logName)
jumpTo(pageName)
}
Вышеприведенный код действительно выглядит более освежающим. Умство этого метода заключается в том, что условие оценки используется в качестве имени атрибута объекта, а логика обработки используется в качестве значения атрибута объекта. осуществляется путем поиска признака объекта.Логическое суждение, этот способ записи особенно подходит для случая унарного условного суждения.
Есть ли другой способ написать это? немного:
const actions = new Map([
[1, ['processing','IndexPage']],
[2, ['fail','FailPage']],
[3, ['fail','FailPage']],
[4, ['success','SuccessPage']],
[5, ['cancel','CancelPage']],
['default', ['other','Index']]
])
/**
* 按钮点击事件
* @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
*/
const onButtonClick = (status)=>{
let action = actions.get(status) || actions.get('default')
sendLog(action[0])
jumpTo(action[1])
}
Круче написать объект Map в es6 таким образом? В чем разница между объектом Map и объектом Object?
- Объект обычно имеет свой собственный прототип, поэтому объект всегда имеет ключ «прототип».
- Ключ объекта может быть только строкой или символами, но ключ карты может быть любым значением.
- Вы можете легко получить количество пар ключ-значение карты через свойство размера, в то время как количество пар ключ-значение объекта можно подтвердить только вручную.
Нам нужно эскалировать проблему. Раньше нам нужно было судить только о статусе, когда кнопка была нажата, а теперь нам также нужно судить о личности пользователя:
/**
* 按钮点击事件
* @param {number} status 活动状态:1开团进行中 2开团失败 3 开团成功 4 商品售罄 5 有库存未开团
* @param {string} identity 身份标识:guest客态 master主态
*/
const onButtonClick = (status,identity)=>{
if(identity == 'guest'){
if(status == 1){
//do sth
}else if(status == 2){
//do sth
}else if(status == 3){
//do sth
}else if(status == 4){
//do sth
}else if(status == 5){
//do sth
}else {
//do sth
}
}else if(identity == 'master') {
if(status == 1){
//do sth
}else if(status == 2){
//do sth
}else if(status == 3){
//do sth
}else if(status == 4){
//do sth
}else if(status == 5){
//do sth
}else {
//do sth
}
}
}
Простите, что не прописываю конкретную логику в каждом решении, потому что код слишком многословен.
Простите меня за использование if/else снова, потому что я вижу, что многие люди все еще используют if/else для написания таких больших логических суждений.
Из приведенного выше примера мы видим, что когда ваша логика будет обновлена до двоичной оценки, количество ваших оценок будет удвоено, а объем вашего кода будет удвоен.Как вы можете писать более освежающе в это время?
const actions = new Map([
['guest_1', ()=>{/*do sth*/}],
['guest_2', ()=>{/*do sth*/}],
['guest_3', ()=>{/*do sth*/}],
['guest_4', ()=>{/*do sth*/}],
['guest_5', ()=>{/*do sth*/}],
['master_1', ()=>{/*do sth*/}],
['master_2', ()=>{/*do sth*/}],
['master_3', ()=>{/*do sth*/}],
['master_4', ()=>{/*do sth*/}],
['master_5', ()=>{/*do sth*/}],
['default', ()=>{/*do sth*/}],
])
/**
* 按钮点击事件
* @param {string} identity 身份标识:guest客态 master主态
* @param {number} status 活动状态:1 开团进行中 2 开团失败 3 开团成功 4 商品售罄 5 有库存未开团
*/
const onButtonClick = (identity,status)=>{
let action = actions.get(`${identity}_${status}`) || actions.get('default')
action.call(this)
}
Основная логика приведенного выше кода: объединение двух условий в строку, а также поиск и выполнение объекта Map с условной строкой объединения в качестве ключа и функцией обработки в качестве значения.Этот способ записи особенно полезен при оценке нескольких условий. .
Конечно, приведенный выше код аналогичен, если он реализован с объектами Object:
const actions = {
'guest_1':()=>{/*do sth*/},
'guest_2':()=>{/*do sth*/},
//....
}
const onButtonClick = (identity,status)=>{
let action = actions[`${identity}_${status}`] || actions['default']
action.call(this)
}
Если некоторые учащиеся считают, что записывать условия запроса в виде строк немного неудобно, есть другое решение, заключающееся в использовании объекта Map и объекта Object в качестве ключа:
const actions = new Map([
[{identity:'guest',status:1},()=>{/*do sth*/}],
[{identity:'guest',status:2},()=>{/*do sth*/}],
//...
])
const onButtonClick = (identity,status)=>{
let action = [...actions].filter(([key,value])=>(key.identity == identity && key.status == status))
action.forEach(([key,value])=>value.call(this))
}
Это немного более продвинуто?
Здесь также можно увидеть разницу между Картой и Объектом.Карта может использовать любой тип данных в качестве ключа.
Теперь давайте немного повысим сложность. Что, если логика обработки статусов 1-4 одинакова в гостевом случае. В худшем случае это так:
const actions = new Map([
[{identity:'guest',status:1},()=>{/* functionA */}],
[{identity:'guest',status:2},()=>{/* functionA */}],
[{identity:'guest',status:3},()=>{/* functionA */}],
[{identity:'guest',status:4},()=>{/* functionA */}],
[{identity:'guest',status:5},()=>{/* functionB */}],
//...
])
Лучший способ написать это — кэшировать логическую функцию обработки:
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
return new Map([
[{identity:'guest',status:1},functionA],
[{identity:'guest',status:2},functionA],
[{identity:'guest',status:3},functionA],
[{identity:'guest',status:4},functionA],
[{identity:'guest',status:5},functionB],
//...
])
}
const onButtonClick = (identity,status)=>{
let action = [...actions()].filter(([key,value])=>(key.identity == identity && key.status == status))
action.forEach(([key,value])=>value.call(this))
}
Этот способ написания уже может удовлетворить повседневные потребности, но если серьезно, то все еще немного неудобно переписывать вышеописанную функцию A 4. Если условия суждения становятся очень сложными, например, личность имеет 3 состояния, а статус имеет 10 состояний, то вы нужно определить 30 частей логики обработки, и часто многие из этих логик одинаковы.Похоже, это то, что автор не хочет принимать.Это может быть реализовано так:
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
return new Map([
[/^guest_[1-4]$/,functionA],
[/^guest_5$/,functionB],
//...
])
}
const onButtonClick = (identity,status)=>{
let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
action.forEach(([key,value])=>value.call(this))
}
Преимущества карты здесь более заметны, и в качестве ключей можно использовать обычные типы, поэтому возможности безграничны.Если спрос становится, для всех гостевых ситуаций должна быть отправлена скрытая точка журнала, а различные ситуации состояния также требуют отдельной логической обработки. , то мы Это можно записать так:
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
const functionC = ()=>{/*send log*/}
return new Map([
[/^guest_[1-4]$/,functionA],
[/^guest_5$/,functionB],
[/^guest_.*$/,functionC],
//...
])
}
const onButtonClick = (identity,status)=>{
let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
action.forEach(([key,value])=>value.call(this))
}
То есть, используя характеристики цикла массива, будет выполняться логика, которая соответствует обычным условиям, тогда общая логика и индивидуальная логика могут выполняться одновременно.Из-за существования регулярности вы можете раскройте свое воображение, чтобы открыть больше способов игры, и в этой статье мы не будем вдаваться в подробности. .
Суммировать
Эта статья научила вас 8 способам написания логических суждений, в том числе:
- if/else
- switch
- При унарном решении: сохранить в объекте
- При унарном решении: сохранить на карте
- Для множественных суждений: соединение условия в строку и сохранение его в объекте
- Для множественных суждений: объединение условия в строку и сохранение его на карте.
- Для нескольких суждений: сохраните условие как объект и сохраните его на карте.
- При множественных суждениях: записывайте условие как обычное и сохраняйте его в Карте
На этом статья тоже подходит к концу.Пусть в вашей будущей жизни будет не только if/else/switch.
Если вас заинтересовала эта статья, подпишитесь на публичный аккаунт автора в WeChat: «Да Чжуань Чжуань Фэ».