Cet article vous présente des méthodes d'écriture technique (exemples de code) sur les jugements logiques complexes en JavaScript. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Lorsque nous écrivons du code js, nous rencontrons souvent des jugements logiques complexes. Habituellement, nous pouvons utiliser if/else ou switch pour implémenter plusieurs jugements conditionnels, mais cela posera un problème à mesure que la logique deviendra plus complexe. À mesure que la vitesse 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 donnera un essai.
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') } }
Vous pouvez voir la logique de clic de ce bouton à travers le code : faire selon différents états d'activité Deux choses, envoyer des logs et accéder à la page correspondante Vous pouvez facilement proposer un plan de réécriture pour ce code qui 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 plus clair que if/else. De plus, les étudiants attentifs ont également découvert une petite astuce. Lorsque la logique du cas 2 et du cas 3 est la même, l'instruction d'exécution et le break peuvent être omis, 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 d'écrire plus simple :
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 a l'air plus propre. La chose intelligente à propos de cette méthode est que : le jugement. condition En tant que nom d'attribut de l'objet, la logique de traitement est utilisée comme valeur d'attribut de l'objet Lorsque vous cliquez sur le bouton, un jugement logique est effectué via la recherche d'attributs d'objet. Cette méthode d'écriture est particulièrement adaptée au jugement conditionnel unaire.
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. La clé d'un objet ne peut être qu'une chaîne ou des symboles, mais la clé d'une carte peut ê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 du statut 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. pour ne pas avoir écrit la logique spécifique de chaque jugement, 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 de cette façon. d'écriture Il est particulièrement utile pour juger plusieurs conditions.
Bien sûr, si le code ci-dessus est implémenté à l'aide d'objets 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) } 如果有些同学觉得把查询条件拼成字符串有点别扭,那还有一种方案,就是用Map对象,以Object对象作为key: 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-il 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 */ }], //... ])
Meilleure écriture. La méthode consiste à mettre en 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 ainsi peut déjà répondre aux besoins quotidiens, mais pour être sérieux, il est quand même un peu inconfortable de réécrire la fonction A 4 fois ci-dessus si la condition de jugement devient. particulièrement compliqué. 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, il y a donc des possibilités infinies si la demande change, un point d'enfouissement de journaux doit être envoyé pour tous. Les situations d'invité et les différentes situations de statut doivent également être séparées. Le traitement logique, alors nous pouvons é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 régulières le fera. être exécuté, alors la logique commune et la logique individuelle peuvent être exécutées en même temps, car régulière Avec son existence, vous pouvez ouvrir votre imagination et débloquer plus de façons de jouer, ce que je n'entrerai pas dans les détails dans cet article.
Cet article vous a appris 8 façons d'écrire des jugements logiques, notamment :
if/else
commutateur
Lorsque vous jugez par un élément : enregistrez-le dans Objet
Lorsque vous jugez par un élément : enregistrez-le dans Map
Lorsque vous effectuez plusieurs jugements : divisez la condition en une chaîne et enregistrez-la dans l'objet
Lorsque vous effectuez plusieurs jugements : Coupez la condition en une chaîne et enregistrez-la dans In Map
Lorsque vous effectuez plusieurs jugements : enregistrez la condition en tant qu'objet et enregistrez-la dans Map
Lorsque vous effectuez plusieurs jugements : enregistrez la condition en tant qu'expression régulière dans Map里
À ce stade, cet article prendra fin, j'espère que vous n'aurez pas seulement if/else. /changer dans votre vie future.
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!