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

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

coldplay.xixi
coldplay.xixiavant
2020-06-16 16:54:012591parcourir

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

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 les détails spécifiques de chaque jugement Logic, car le code est trop verbeux.

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([
  ['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)
}复制代码

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 = {  'guest_1':()=>{/*do sth*/},  'guest_2':()=>{/*do sth*/},  //....}const onButtonClick = (identity,status)=>{  let action = actions[`${identity}_${status}`] || actions['default']
  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:'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))
}复制代码

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:'guest',status:1},()=>{/* functionA */}],
  [{identity:'guest',status:2},()=>{/* functionA */}],
  [{identity:'guest',status:3},()=>{/* functionA */}],
  [{identity:'guest',status:4},()=>{/* functionA */}],
  [{identity:'guest',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:'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))
}复制代码

É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, par exemple, l'identité a 3 états et le statut a 10 états. 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. implémenté comme ceci :

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))
}复制代码

Les avantages de Map sont plus importants ici. Les types réguliers peuvent être utilisés comme clés, ce qui ouvre des possibilités illimitées, si la demande change, 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é. Ensuite, nous pouvons l'é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. peut exécuter la logique publique et la logique individuelle en même temps. En raison de l'existence de règles régulières, vous pouvez ouvrir votre imagination. Pour débloquer plus de façons de jouer, 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 avec un élément : enregistrez-le dans un objet
  4. Lors d'un jugement avec un élément : enregistrez-le dans la carte
  5. Lors d'un jugement avec plusieurs éléments : divisez la condition en une chaîne et enregistrez-la dans Objet
  6. Éléments multiples Lors d'un jugement : concaténez la condition en une chaîne et enregistrez-la dans la carte
  7. Lors de jugements multiples : enregistrez la condition en tant qu'objet et enregistrez-la dans la carte
  8. Lorsque vous portez plusieurs jugements : écrivez la condition sous forme d'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. if/else/switch dans votre vie future.

Si cet article vous intéresse, veuillez suivre le compte public WeChat de l'auteur : "大 Zhuanzhuanfe"

Tutoriel recommandé : "Tutoriel sur les bases de JavaScript

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