代码之家  ›  专栏  ›  技术社区  ›  Marko

switch case语句中的表达式

  •  28
  • Marko  · 技术社区  · 14 年前

    我试图创建一个switch语句,但是我似乎不能使用一个得到计算的表达式(而不是一个集合字符串/整数)。我可以很容易地做到这一点,如果语句,但案件应该希望更快。

    我正在尝试以下方法

    function reward(amount) {
        var $reward = $("#reward");
        switch (amount) {
            case (amount >= 7500 && amount < 10000):
                $reward.text("Play Station 3");
                break;
            case (amount >= 10000 && amount < 15000):
                $reward.text("XBOX 360");
                break;
            case (amount >= 15000):
                $reward.text("iMac");
                break;
            default:
                $reward.text("No reward");
                break;
        }
    }
    

    我是错过了一些明显的东西还是这是不可能的?谷歌在这件事上并不友好。

    感谢您的帮助/指点

    8 回复  |  直到 14 年前
        1
  •  139
  •   MooGoo    14 年前

    你可以一直这样做

    switch (true) {
      case (amount >= 7500 && amount < 10000):
        //code
        break;
      case (amount >= 10000 && amount < 15000):
        //code
        break;
    
      //etc...
    

    它起作用是因为 true 是常量,因此将执行第一个case语句下的代码,该语句的表达式的计算结果为true。

    我想这有点“棘手”,但我觉得用它没什么错。一个简单的 if/else 声明可能会更简洁,而且您不必担心意外的失败。但不管怎样,它还是在那里。

        2
  •  11
  •   Community Egal    7 年前

    switch (true) 会给你一个 Weird condition error in jsLint ,所以让我们更具创造性,以防出现问题,并且,我认为,增加可读性。

    case true false 的值等于 switch 期限。所以让我们用速记法来利用这一点 if 进入我们的 案例 声明和 .

    关键词: case (x > 0 ? x : null):

    “如果我的任期, x x === x 我负责办案。”

    http://jsfiddle.net/rufwork/upGH6/1/

    /*global document*/
    /*jslint evil:true*/
    var x = 10;
    
    switch (x) {
        case (x > 0 ? x : null):
            document.write('ha ha ha!  I fooled switch AND jsLint!  Muhahahahaha!');
            break;
        case 0:
            document.write('zero is nothing.');
            break;
        case -1:
            document.write('low');
            break;
        case -2:
            document.write('lower');
            break;
        case -3: 
            document.write('lowest I care about');
            break;
        default: // anything lower than -3.
            document.write('TOO LOW!!!! (unless you cheated and didn\'t use an int)');
    }
    document.write('<br>done.');
    
        3
  •  9
  •   Daniel A. White    7 年前

    这不是一个 switch 砌块工程。这个 case 转换 线路。 if-else

    这里有一些关于 转换 阻止。

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

        4
  •  4
  •   dotnetCarpenter    8 年前

    好吧,你可以用英语表达 case 语句,这就是为什么您的开关不是语法错误。但你必须明白 Case子句 switch(expression)

    函数调用是表达式,所以让我们尝试一下:

    function xbox(amount) { return amount >= 10000 && amount < 15000 && amount; }
    
    function reward(amount) {
      var ps3 = function(amount) { return amount >= 7500 && amount < 10000 && amount; }
    
      function imac(amount) { return amount >= 15000 && amount; }
    
      var $reward = $("#reward");
      switch (amount) {
        case ps3(amount):
          $reward.text("Play Station 3");
          break;
        case xbox(amount):
          $reward.text("XBOX 360");
          break;
        case imac(amount):
          $reward.text("iMac");
          break;
        default:
          $reward.text("No reward");
          break;
      }
    }
    reward(8200)// -> Play Station 3
    reward(11000)// -> XBOX 360
    reward(20000)// -> iMac
    

    如您所见,您可以同时使用函数表达式和函数定义。没关系。只有case子句中的表达式是要计算的表达式。这与您所做的相同,只是您没有返回一个与金额相同的值,而是一个真值或假值。在我的示例中,如果我的条件为真,则返回确切的数量,因此触发比较以匹配。

    function reward(amount) {
        var $reward = $("#reward");
        switch (amount) {
            case (amount >= 7500 && amount < 10000 && amount):
                $reward.text("Play Station 3");
                break;
            case (amount >= 10000 && amount < 15000 && amount):
                $reward.text("XBOX 360");
                break;
            case (amount >= 15000 && amount):
                $reward.text("iMac");
                break;
            default:
                $reward.text("No reward");
                break;
        }
    }
    

    规格如下: https://tc39.github.io/ecma262/#sec-switch-statement 链接到es2016是因为它比1999年的旧es3 pdf更容易查找。但它一直是这样工作的,但这是一个鲜为人知的事实。

    if 声明。如果你想跑得快,那么 触摸DOM。

        5
  •  2
  •   robert    10 年前

    你也可以试试我最喜欢的一种结构:

    function reward(amount) {
        var $reward = $("#reward");
        $reward.text(
            (amount >= 7500 && amount < 10000) ?    "Play Station 3" :
            (amount >= 10000 && amount < 15000)?    "XBOX 360" :
            (amount >= 15000) ?                     "iMac" :
                                                    "No reward"
        );
    }
    
        6
  •  1
  •   Fyodor Soikin    14 年前

    首先,不是这样的 switch 作品。您必须为每个 case ,这些常量将与括号中的表达式进行比较(在您的示例中, amount

    其次,切换速度不超过几个 if s

    第三,在处理javascript时,您不应该真的担心微小的性能优化。

        7
  •  1
  •   sth Wojciech Parzych    12 年前

    switch表达式设置为true的解决方案之所以有效,不是因为true是一个常量,而是因为实际上可以与case表达式相等。

    不是说必须为每个case表达式指定常量。

    要支持我的回答,请参阅Douglas Crockford,Javascript The Good Parts(2008),第12页:

    switch语句执行多路分支。它将等式表达式与所有选定的情况进行比较。。。。当找到完全匹配时,将执行匹配case子句的语句。。。case子句包含一个或多个case表达式。case表达式不必是常量。

        8
  •  1
  •   GNM    8 年前

    我的2美分:

    理想情况下,switch(作为一个原则)应该计算为一个case分支,从而实现O(1)性能,并且case语句可以以任何方式重新排序(而不是遍历case),而无需更改编译器分支策略。

    如果使用表达式(假设语言允许),那么理论上,它可以遵循多个分支。

    编译器(除了那些能够智能地说出开发人员正在尝试做什么的编译器)将无法静态地优化分支策略,因此在理想情况下会失去其有效性。

    例子:

    var x = 6, factors = [];
    
    switch(x){
    
        case (x%2 == 0): factors.push(2);
        break;
    
        case (x%3 == 0): factors.push(3);
        break;
        ....
     }
    

    {希望对糟糕的代码有评论}

    在上面的示例中,编译器没有实际的方法进行静态优化,因此与if-else相比没有获得任何性能优势。

    唯一的部分是,它“可能”看起来更清洁的开发商,但实际上可能是中断的情况下,额外的条件。