我可以使用带有两个变量的case/switch语句吗?

65

当涉及JavaScript时,我是一个新手,我的理解是使用一个SWITCH/CASE语句比使用一堆IF语句更快。

然而,我想使用一个包含两个变量的SWITCH/CASE语句。

我的Web应用有两个滑块,每个滑块有五种状态。我希望行为是基于这两个变量的状态。显然,这是许多IF/THEN语句。

我想到的一种方法是将两个变量连接成一个,然后我可以使用SWITCH/CASE语句。

是否有更好的方法来使用两个变量进行SWITCH/CASE操作?

谢谢!


1
这些变量里面是什么?数字?字符串? - Madara's Ghost
3
25个案例表达式?!那个方法会非常庞大。 :-o 你确定需要为所有25个状态编写单独的逻辑吗? - Mark Byers
如果您有大量选项,那么简单地将它们连接起来,比如 var1|var2 可能是一种非常快速的方法。不过,我们需要看看您正在做什么的一些示例... - Michael Berkowski
1
可能有更好的方法来解决你的问题。如果你提供更多关于实际问题的信息,你可能会得到很多好的建议 :) - benekastah
其实有点复杂。我正在使用ArcGIS Javascript API,并根据滑块的位置显示不同的地图。我真正想做的是使用滑块进行一些计算,然后根据这些计算显示地图,但效果并不理想。 - user918967
9个回答

54

是的,你也可以这样做:

    switch (true) {

     case (var1 === true && var2 === true) :
       //do something
       break;
     case (var1 === false && var2 === false) :
       //do something
       break;

      default:

    }

这将始终执行switch,几乎就像if/else一样,但看起来更干净。只需在case表达式中继续检查您的变量即可。


1
不错,但是 TypeScript 不接受这个解决方案。 - Alexey Nikonov
1
@AlexeyNikonov 对我来说是可以的。 - Creative
1
@AlexeyNikonov 对我来说是这样的。 - Creative

33

如何使用位运算符?与其处理字符串,您将处理“枚举”,这看起来更加“优雅”。

// Declare slider's state "enum"
var SliderOne = {
    A: 1,
    B: 2,
    C: 4,
    D: 8,
    E: 16
};

var SliderTwo = {
    A: 32,
    B: 64,
    C: 128,
    D: 256,
    E: 512
};

// Set state
var s1 = SliderOne.A,
    s2 = SliderTwo.B;

// Switch state
switch (s1 | s2) {
    case SliderOne.A | SliderTwo.A :
    case SliderOne.A | SliderTwo.C :
        // Logic when State #1 is A, and State #2 is either A or C
        break;
    case SliderOne.B | SliderTwo.C :
        // Logic when State #1 is B, and State #2 is C
        break;
    case SliderOne.E | SliderTwo.E :
    default:
        // Logic when State #1 is E, and State #2 is E or
        // none of above match
        break;


}

我同意其他人的看法,使用switch-case逻辑处理25个情况并不太美观,有时候if-else可能“看起来”更好。无论如何。


单个 | 还是双个 || - itsazzad
2
单个。我们在谈论“按位或”运算符。参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators - Stachu
当枚举未在位范围内定义时,这将无法工作,因此这是一条误导性的指令。 - Lauri Larjo
这样做可能会很高效,但不利于可读性。并非每个开发人员都理解位运算。 - GeorgiG

26
var var1 = "something";
var var2 = "something_else";
switch(var1 + "|" + var2) {
    case "something|something_else":
        ...
        break;
    case "something|...":
        break;
    case "...|...":
        break;
}

如果每个选项有5种可能性,那么你将得到25种情况。


61
这个和其他所有答案一样糟糕。正确的答案是使用if... - BlueRaja - Danny Pflughoeft
考虑以下情况:var1 = "something|something_else";var2 = ""; - Brian Hannay
如果插入了额外的 |,那么情况将变成 "something|something_else|". 虽然不是很好,但我的答案假设您完全控制 var1var2. 如果您假设没有完全控制它们,那你的答案会是什么? - Halcyon
@Halcyon 我认为没有非常好的方法来解决这个问题,但是可以使用嵌套的switch语句(带有变量选项)来实现。我只是想不出在OP问题中第二个滑块的结果动作会依赖于第一个滑块的值的情况。 - Brian Hannay
1
@BlueRaja-DannyPflughoeft 真的没错 :) - Pranav A.
显示剩余2条评论

15

首先,JavaScript 中的 switchif/else 相比速度并没有更快(有时甚至更慢)。

其次,使用 switch 处理多个变量的唯一方法是将它们合并为一个原始值(字符串、数字等):

var stateA = "foo";
var stateB = "bar";
switch (stateA + "-" + stateB) {
    case "foo-bar": ...
    ...
}

但是,就个人而言,我更愿意看到一组if/else语句。

编辑:当所有值都是整数时,似乎在Chrome中使用switch可以比if/else更快。请参见评论。


1
重复相同的测试,但是使用100个案例。差异将变得明显。 - Rob W
啊,在我的浏览器上,当被切换的值是整数时,你似乎是正确的:http://jsperf.com/switch-ifelse-map/3 - David Wolever
不一定是整数。但你需要修改测试用例。哈希表通常是 switchelse if{} 中最有效的选项。当经常进行检查时,创建哈希表的开销变得可以忽略不计。它在长期运行中胜过了 switchelse if - Rob W
哦,糟糕了,看起来我的数字测试用例被字符串测试用例覆盖了。不管怎样,数字更快,字符串相同。 - David Wolever
嗨,David,谢谢,能够比较整数和字符串的switch和if/else是相当棒的。似乎在FF9.01中,使用switch和整数是最快的。 - user918967
1
测试链接现在已经失效。 - Obed Parlapiano

6

我不相信switch/case比一系列的if/elseif更快。它们做相同的事情,但是if/elseif可以检查多个变量。你不能在一个值上使用switch/case。


5

如果每个组合的行为都是静态的,您可以构建一个二维数组:

var data = [
  [1,2,3,4,5],
  [6,7,8,9,10],
  [11,12,13,14,15],
  [16,17,18,19,20],
  [21,22,23,24,25]
];

在上面的示例中,数字可以是任何内容,如字符串、数组等。现在获取值只需要一行代码(假设滑块的值范围为[0,5]):
var info = data[firstSliderValue][secondSliderValue];

4

是的,但不是以普通的方式。您将需要使用 switch 作为闭包。

例如:

function test(input1, input2) {
     switch (true) {
        case input1 > input2:
                    console.log(input1 + " is larger than " + input2);
                    break;
        case input1 < input2:
                    console.log(input2 + " is larger than " + input1);
        default:
                    console.log(input1 + " is equal to " + input2);
      }
   }

4

我是这样做的:

switch (valueA && valueB) {

case true && false:
console.log(‘valueA is true, valueB is false’)
break;

case ( true || false ) && true:
console.log(‘valueA is either true or false and valueB is true’)
break;

default:
void 0;
}

4
您可以为每个滑块上的每个位置分配不同的二进制值,范围从1到1000000000,然后对其求和进行处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接