我有一个JavaScript函数,它有多个嵌套的开关用例,这完全是一团糟。在过去的几个月里,该功能已经扩展,现在我想重组代码。在任何情况下,都应该将不同的值推送到已经存在的变量中
下面是我的代码示例:
switch(var1){
case 1:
switch(var2){
case 0:
switch(var3){
case 'test':
switch(i){
case 0: endresult.push({id: i, content: '123'}); break;
case 2: endresult.push({id: i, content: '124'}); break;
}
break;
default:
endresult.push({id: i, content: '125'}); break;
}
break;
case 1:
endresult.push({id: i, content: '126'}); break;
}
break;
case 2:
switch(var2){
case 0:
switch(i){
case 0: endresult.push({id: i, content: '127'}); break;
case 2: endresult.push({id: i, content: '128'}); break;
}
break;
case 1:
switch(i){
case 0: endresult.push({id: i, content: '128'}); break;
case 2: endresult.push({id: i, content: '129'}); break;
}
break;
}
break;
}
重写这篇文章的最佳方式是什么?
拥有所有可能变化及其值的映射:
// Key is composite of `"" + var1 + "_" + var2 + "_" + i` and trimmed `_` from back
let tree = {
'1_0_test_0': '123',
'1_0_test_2': '124',
'1_0_test': '125',
'1_0_1': '126',
...
}
let key = ("" + var1 + var2 + i).replace(/_{2,}|_+$/, '');
if (typeof tree[key] !== 'undefined') {
endresult.push({id: i, content: tree[key]});
}
您关心的是可读性,对吗?您可能需要对代码进行一点拆分。并使用变量名,而不是0和1。此外,您还需要提供更多详细信息。比如它可以超越0和1到2和3等等。我不确定你是如何调用你的代码的。
然而,您可以尝试(混合对象和其他对象):
const decideFn = ({ var1, var2, var3, i }) = {
const decision = {
1: {
0: {
cond(i) {
if (var3 === 'test') {
if (i === 0)
endresult.push({id: i, content: '123'})
else if (i === 2)
endresult.push({id: i, content: '124'})
else
endresult.push({id: i, content: '125'})
}
else endresult.push({id: i, content: '125'})
}
},
1: {
cond(i) {
endresult.push({id: i, content: '126'})
}
}
}
2: {
0: {
cond(i) {
if (i === 0)
endresult.push({id: i, content: '127'})
else if (i === 2)
endresult.push({id: i, content: '128'})}
},
1: {
cond(i) {
if (i === 0)
endresult.push({id: i, content: '128'})
else if (i === 2)
endresult.push({id: i, content: '129'})
}
}
}
}
// usage
// does i go in a loop ?
// your qn needs more details. but i hope you get the idea
decision[var1][var2].cond(i)
}
最终,它实际上可以归结为你觉得自己最了解代码,以及其他开发人员会如何阅读你的代码,但我个人认为你的switch语句很好。
不过,对象可能会提供更大的灵活性。
如果在每种情况下你都在推送同一个变量,我会考虑创建一个函数,它的唯一工作是根据变量确定正确的值。
这可能看起来像这样:
const getContentValue(var1, var2, var3, i) {
if (var1 === 1) {
if (var2 === 0) {
if (var3 === 'test') {
if (i === 0) return '123'
if (i === 2) return '124'
return '125'
}
if (var2 === 1) {
return '126'
}
}
if (var1 === 2) {
if (var2 === 0) {
if (i === 0) return '127'
if (i === 2) return '128'
}
if (var2 === 1) {
if (i === 0) return '128'
if (i === 2) return '129'
}
}
}
endResult.push({ id: i, content: getContentValue(var1, var2, var3, i) })
(代码未经测试。)
需要注意的几件事和需要遵循的几条原则:
- 基本的";决策结构";是相同的,但通过使用
if
语句进行了简化。在我看来,在案件之间切换是当你有很多案件时你会做的事情,而不是当你在两件事之间切换时。当您在两个选项之间切换时,if
语句非常有效。如果你真的在处理一堆案例,比如你的var1实际上可能是10+个不同的数字,那么使用switch
可能更简单 - 如果您查看代码中的
switch
语句,那么对于每种情况都有很多相同的内容。一个技巧是观察每种情况下答案的变化。CCD_ 5是相同的。只有数字会改变。这是一条简化事物的好路 - 我不认为这是故意的,但有两种情况会导致数字128。您可能可以做一些额外的简化。(很难确切地知道,因为我知道你所掌握的样本数据并不完全是你正在处理的真实数据。)我之所以发表评论,是因为这实际上是一个很好的教学时刻——如果你有完全相同的最终案例,那就需要好好看一看
- 注意
switch
语句和if
语句的概念之间的相似性。在函数中,如果您有一个return语句,它的作用将类似于switch
语句的break
。如果您在每个if
案例之后返回,那么当您有足够的信息知道返回内容时,您将获得相当于default
案例的信息。(例如,请参阅写着return '125'
的行。我们知道,如果我们达到这一点,应该返回125。)