繁体   English   中英

有没有更好的方法用JavaScript编写此开关?

[英]Is there a better way to write this switch in JavaScript?

我有以下条件的switch

  • 第一种case是三个名称(ROKA,MOKA和TOKA)之间or之间。

  • 第二种case是另一个名称(KOKA),但具有两个附加条件来显示alert

  • 最后,我还有其他条件需要检查default块,因为我无法为它们使用case

这是我的代码:

var myname= 'JOKA';
var dhaba = false;

switch (myname) {
  case ('ROKA'):
  case ('MOKA'):
  case ('TOKA'):
    alert('EEE');
    break;

  case ('KOKA'):
    // This will work as Goto to final default:

    if (condition1 && condition2) {
      alert('FEEE');
      break;
    }

  default:
    if (dhaba && myname != 'ROKA' && myname != 'TOKA') {
      alert('TEEEE');
    } else {
      alert('CHEEE');
    }
}

有没有更好的方法来编写此代码?

当达到defaultmyname始终不等于先前检查的值。 使用就足够了

default:
    if (dhaba) {
        alert('TEEEE');
    } else {
        alert('CHEEE');
    }

我认为对于您的用例而言, switch不是最佳选择。

另外,正如@NinaScholz所指出的, myname != 'ROKA' && myname != 'TOKA'将始终为true,否则您将陷入第一种case

让我们一步一步来看看重构代码的不同方法:

👌简化(非开关)代码

编写代码的最简单,最直接的方法是这样的:

const myname = 'JOKA';
const dhaba = false;

if ('ROKA' === myname || 'MOKA' === myname || 'TOKA' === myname) {
    alert('EEE');
} else if (myname === 'KOKA' && true && true) {
    alert('FEEE');
} else {
    alert(dhaba ? 'TEEEE' : 'CHEEE');
}

请注意,如何删除冗余检查,以及如何用三元运算符替换最后一个if- if - else块。


您的代码可能与您提供的示例不完全相同,或者可能随着时间的推移而更改。 在这种情况下,您可以考虑上述简化代码以外的其他选项。

using使用Array.prototype.indexOf()从单个变量检查​​多个匹配项

但是,第一个if元素可能还有很多要检查的元素。 在那种情况下,您可以使用ArrayArray.prototype.indexOf()来检查内部是否有任何匹配项(如果没有匹配项,则返回-1 ):

const myname = 'JOKA';
const dhaba = false;

if (['ROKA', 'MOKA', 'TOKA'].indexOf(myname) !== -1) {
    alert('EEE');
} else if (myname === 'KOKA' && true && true) {
    alert('FEEE');
} else {
    alert(dhaba ? 'TEEEE' : 'CHEEE');
}

👉N输入-输出(字符串)对+带有开关的复杂默认值

也有可能有多个myname值映射到多个alert()参数,因此您可能会想写这样的东西:

const myname = 'JOKA';
const dhaba = false;

switch(myname) {
    case 'XXX-1': alert('YYY-1'); break;
    case 'XXX-2': alert('YYY-2'); break;

    ...

    case 'XXX-N': alert('YYY-N'); break;

    default:
        if (myname === 'KOKA' && true && true) {
            alert('FEEE');
        } else {
            alert(dhaba ? 'TEEEE' : 'CHEEE');
        }
}

尽管这很好,并且实际上,我认为这比检查case块中的其他条件(如您在示例中所做的那样)更干净,而且更不容易出错,但基于此,您可以做些事情并break或让下一个块执行,我建议您考虑改用对象文字查找。

👉N个输入-输出(字符串)对+具有对象文字查找的复数默认值🔎

使用它们有多个优点:更好的可读性,更容易的调试,可维护性,简洁(例如,无需添加break )...我认为,对您来说,最重要的一项是在问题中添加了标签performance ,表现更好。

这是因为尽管switch必须评估每种case条件,直到找到break为止,所以它们的顺序很重要,但对象查找只是哈希表查找,即O(1)

考虑到这一点,我们可以像这样重构最后一个示例:

const myname = 'JOKA';
const dhaba = false;

const output = {
    'XXX-1': 'YYY-1',
    'XXX-2': 'YYY-2',

    ...

    'XXX-N': 'YYY-N',
}[myname];

// Note output will be undefined if there isn't a match, so the first if
// will be evaluated to false in that scenario:

if (output) {
    alert(output);
} else if (myname === 'KOKA' && true && true) {
    alert('FEEE');
} else {
    alert(dhaba ? 'TEEEE' : 'CHEEE');
}

👉N个输入-输出(字符串)对+具有对象文字查找Single和||的单值默认值 (或)运算符

另外,请注意,如果您的默认值只是在if内使用另一个值, if可以使用简单的|| 操作员:

const myname = 'JOKA';

const output = {
    'XXX-1': 'YYY-1',
    'XXX-2': 'YYY-2',

    ...

    'XXX-N': 'YYY-N',
}[myname] || 'DEFAULT OUTPUT';

alert(output);

👉N个输入-输出(任意代码)对与对象文字查找

请注意,您还可以使用functionsarrow functions针对对象中的每种情况执行任意代码:

const myname = 'JOKA';

const output = {
    'XXX-1': () => { /* Do something... */ },
    'XXX-2': () => { /* Do something... */ },

    ...

    'XXX-N': () => { /* Do something... */ },
}[myname]();

...

请注意,您可以在对象声明上方声明这些functions ,并在应该具有相同行为的多个键之间共享它们:

const myname = 'JOKA';

const f1 = () => { /* Do something 1... */ };

const output = {
    'XXX-1': f1,
    'XXX-2': f1,

    ...

    'XXX-N': () => { /* Do something... */ },
}[myname]();

...

有关使用对象文字查找替换switchs更多信息,请参见以下文章: https : //toddmotto.com/deprecating-the-switch-statement-for-object-literals

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM