我有一个switch
,其中包含以下条件:
第一个case
是三个名称之间的or
(ROKA,MOKA和TOKA)。
第二个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');
}
}
有没有更好的方法来编写此代码?
答案 0 :(得分:1)
当您到达default
时,myname
始终不等于之前检查的值。使用
default:
if (dhaba) {
alert('TEEEE');
} else {
alert('CHEEE');
}
答案 1 :(得分:1)
我认为switch
不是您用例的最佳选择。
另外,正如@NinaScholz指出的那样,myname != 'ROKA' && myname != 'TOKA'
将始终为真,否则您将落入第一个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 - else
块替换为ternary operator。
您的代码可能与您提供的示例完全不同,或者它会随着时间的推移而改变。在这种情况下,您可以考虑除上述简化代码之外的其他选项。
但是,您可能需要在第一个if
中检查更多元素。在这种情况下,您可以使用Array
和Array.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');
}
您可能还有多个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
块中检查其他条件更清晰且更不容易出错,就像在您的示例中所做的那样,并且基于它做了一些事情{ {1}}或者让下一个块执行,我建议你考虑使用对象文字查找。
使用它们有多个优点:更好的可读性,更容易调试,可维护性,简洁性(例如,无需添加break
)...我认为对您来说最重要的是,因为您添加了在您的问题中标记break
,是否更高效。
这是因为performance
必须评估每个switch
条件,直到f 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');
}
中的其他值,则可以使用简单的if
运算符执行此操作:
||
请注意,您还可以使用const myname = 'JOKA';
const output = {
'XXX-1': 'YYY-1',
'XXX-2': 'YYY-2',
...
'XXX-N': 'YYY-N',
}[myname] || 'DEFAULT OUTPUT';
alert(output);
或functions
为对象中的每个案例执行任意代码:
arrow 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]();
...
的更多信息,请查看以下帖子:https://toddmotto.com/deprecating-the-switch-statement-for-object-literals