Maison  >  Article  >  interface Web  >  Une manière élégante d'écrire des jugements complexes en JavaScript

Une manière élégante d'écrire des jugements complexes en JavaScript

hzc
hzcavant
2020-06-16 09:51:152019parcourir

Prémisse


Nous rencontrons souvent des jugements logiques complexes lors de l'écriture de code js. Habituellement, vous pouvez utiliser if/else ou switch pour implémenter plusieurs jugements conditionnels, mais il y aura un. problème avec cela. À mesure que la complexité logique augmente, le commutateur if/else/dans le code deviendra de plus en plus volumineux et difficile à comprendre. Alors, comment écrire une logique de jugement de manière plus élégante ? Cet article vous permettra d'essayer une fois.

Par exemple

Regardez d'abord un morceau de code

/**
 * 按钮点击事件
 * @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')
  }
}

À travers le code, vous pouvez voir la logique de clic de ce bouton : faire deux choses en fonction de différents états d'activité, envoyez des logs pour enterrer le point et accéder à la page correspondante. Vous pouvez facilement proposer un plan de réécriture pour ce code. Switch apparaît :

/**
 * 按钮点击事件
 * @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
  }
}

Eh bien, cela semble beaucoup plus clair que if/else. petit Astuce, lorsque la logique du cas 2 et du cas 3 est la même, vous pouvez omettre l'instruction d'exécution et la pause, et la logique du cas 3 sera automatiquement exécutée dans le cas 2.

À l'heure actuelle, certains étudiants diront qu'il existe une manière plus simple d'écrire :

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)
}

Le code ci-dessus semble plus propre. La chose intelligente à propos de cette méthode est qu'elle prend la condition de jugement. en tant qu'objet Le nom de l'attribut utilise la logique de traitement comme valeur d'attribut de l'objet. Lorsque vous cliquez sur le bouton, un jugement logique est effectué en recherchant les attributs de l'objet. Cette méthode d'écriture est particulièrement adaptée aux jugements conditionnels unaires.

Y a-t-il une autre façon de l’écrire ? Certains :

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])
}

Écrire comme ceci utilise l'objet Map dans es6. N'est-ce pas plus amusant ? Quelle est la différence entre l’objet Map et l’objet Object ?

  1. Un objet a généralement son propre prototype, donc un objet a toujours une clé "prototype".

  2. Les clés d'un objet ne peuvent être que des chaînes ou des symboles, mais les clés d'une carte peuvent être n'importe quelle valeur.

  3. Vous pouvez facilement obtenir le nombre de paires clé-valeur d'une carte via l'attribut size, tandis que le nombre de paires clé-valeur d'un objet ne peut être confirmé que manuellement.

Nous devons mettre à jour le problème. Dans le passé, nous n'avions besoin de juger que de l'état en cliquant sur le bouton. Maintenant, nous devons également juger de l'identité de l'utilisateur :

/**
 * 按钮点击事件
 * @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
    }
  }
}
<.>Pardonnez-moi de ne pas avoir écrit tous les jugements. La logique spécifique ici est que le code est trop long.

Pardonnez-moi d'utiliser à nouveau if/else, car je vois que beaucoup de gens utilisent encore if/else pour écrire des jugements logiques aussi longs.

Nous pouvons voir dans l'exemple ci-dessus que lorsque votre logique est mise à niveau vers le jugement binaire, le montant de votre jugement doublera, et le montant de votre code doublera également. Comment écrire de manière plus rafraîchissante à ce moment-là ?

const actions = new Map([
  [&#39;guest_1&#39;, ()=>{/*do sth*/}],
  [&#39;guest_2&#39;, ()=>{/*do sth*/}],
  [&#39;guest_3&#39;, ()=>{/*do sth*/}],
  [&#39;guest_4&#39;, ()=>{/*do sth*/}],
  [&#39;guest_5&#39;, ()=>{/*do sth*/}],
  [&#39;master_1&#39;, ()=>{/*do sth*/}],
  [&#39;master_2&#39;, ()=>{/*do sth*/}],
  [&#39;master_3&#39;, ()=>{/*do sth*/}],
  [&#39;master_4&#39;, ()=>{/*do sth*/}],
  [&#39;master_5&#39;, ()=>{/*do sth*/}],
  [&#39;default&#39;, ()=>{/*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(&#39;default&#39;)
  action.call(this)
}

La logique de base du code ci-dessus est la suivante : fusionnez les deux conditions en une chaîne, puis recherchez et exécutez l'objet Map en utilisant la chaîne conditionnelle comme clé et la fonction de traitement comme valeur. Cette méthode d'écriture est. utilisé dans plusieurs Il est particulièrement utile lors de la prise de jugements conditionnels.

Bien sûr, si le code ci-dessus est implémenté à l'aide d'un objet Object, ce sera similaire :

const actions = {
  &#39;guest_1&#39;:()=>{/*do sth*/},
  &#39;guest_2&#39;:()=>{/*do sth*/},
  //....
}

const onButtonClick = (identity,status)=>{
  let action = actions[`${identity}_${status}`] || actions[&#39;default&#39;]
  action.call(this)
}

Si certains étudiants pensent qu'il est un peu gênant d'épeler les conditions de requête dans une chaîne , alors il existe une autre solution, qui consiste à utiliser un objet Map , en utilisant l'objet Object comme clé :

const actions = new Map([
  [{identity:&#39;guest&#39;,status:1},()=>{/*do sth*/}],
  [{identity:&#39;guest&#39;,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))
}

N'est-ce pas un peu plus avancé ?

La différence entre Map et Object peut également être vue ici. Map peut utiliser n'importe quel type de données comme clé.

Améliorons maintenant un peu la difficulté. Et si la logique de traitement des statuts 1 à 4 était la même dans le cas de l'invité, le pire des cas est le suivant :

const actions = new Map([
  [{identity:&#39;guest&#39;,status:1},()=>{/* functionA */}],
  [{identity:&#39;guest&#39;,status:2},()=>{/* functionA */}],
  [{identity:&#39;guest&#39;,status:3},()=>{/* functionA */}],
  [{identity:&#39;guest&#39;,status:4},()=>{/* functionA */}],
  [{identity:&#39;guest&#39;,status:5},()=>{/* functionB */}],
  //...
])

Une meilleure façon d'écrire. c'est Cache la fonction logique de traitement

const actions = ()=>{
  const functionA = ()=>{/*do sth*/}
  const functionB = ()=>{/*do sth*/}
  return new Map([
    [{identity:&#39;guest&#39;,status:1},functionA],
    [{identity:&#39;guest&#39;,status:2},functionA],
    [{identity:&#39;guest&#39;,status:3},functionA],
    [{identity:&#39;guest&#39;,status:4},functionA],
    [{identity:&#39;guest&#39;,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))
}

Écrire comme ça peut déjà répondre aux besoins quotidiens, mais pour être sérieux, c'est quand même un peu inconfortable de réécrire la fonctionA 4 fois ci-dessus Si la condition de jugement devient particulièrement compliquée, pour. Par exemple, l'identité a 3. Il y a 10 états dans le statut. Ensuite, vous devez définir 30 logiques de traitement, et souvent beaucoup de ces logiques sont les mêmes. Cela semble être quelque chose que je ne veux pas accepter. Cela peut être implémenté comme ça. :

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))
}

Ici, les avantages de Map sont encore plus importants. Les types réguliers peuvent être utilisés comme clés, ce qui ouvre des possibilités illimitées si l'exigence devient qu'un point d'enfouissement de journaux doit être envoyé pour toutes les situations d'invité, et différentes situations d'état nécessitent également un traitement logique séparé, nous pouvons alors écrire comme ceci :

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))
}

En d'autres termes, en utilisant les caractéristiques des boucles de tableau, une logique qui répond aux conditions normales sera ensuite exécutée. et la logique individuelle en même temps. Grâce à l'existence de règles régulières, vous pouvez ouvrir votre imagination et débloquer. Il existe d'autres façons de jouer, que je n'entrerai pas dans les détails dans cet article.

Résumé

Cet article vous a appris 8 façons d'écrire des jugements logiques, notamment :

  1. if/else

  2. changer

  3. Lors d'un jugement d'un yuan : enregistrez-le dans Objet

  4. Lors d'un jugement d'un yuan : enregistrez-le dans Carte

  5. Lors de jugements multiples : divisez la condition en une chaîne et enregistrez-la dans l'objet

  6. Lorsque vous effectuez plusieurs jugements : fusionnez la condition dans une chaîne et enregistrez-la dans la carte

  7. Lorsque vous effectuez plusieurs jugements : enregistrez la condition en tant qu'objet et enregistrez-la dans la carte

  8. Lors de la création de la jugement multivarié : enregistrez la condition en tant qu'expression régulière et enregistrez-la dans la carte

À ce stade, cet article prendra fin, j'espère que vous aurez plus que juste si/. sinon/changez dans votre vie future.

Tutoriel recommandé : "

Tutoriel JS"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer