表达式在switch case语句中

时间:2010-08-12 00:14:08

标签: javascript switch-statement case

我正在尝试创建一个switch语句,但我似乎无法使用得到评估的表达式(而不是设置字符串/整数)。我可以使用if语句轻松完成此操作,但希望案例更快。

我正在尝试以下

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 个答案:

答案 0 :(得分:98)

你可以随时

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

  //etc...

它的工作原理是因为true是一个常量,所以第一个case语句下的代码将被执行。

我觉得这有点“棘手”,但我觉得使用它并没有错。一个简单的if/else陈述可能会更简洁,你不必担心意外跌倒。但无论如何它仍然存在。

答案 1 :(得分:10)

这不是switch块的工作原理。 case用于保存单个值,如果它们等于switch行上的值。 if-else语句将很好地为您服务。

以下是有关switch阻止的一些信息。

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

答案 2 :(得分:10)

@ MooGoo的switch (true)会给你一个Weird condition error in jsLint,所以如果这是一个问题,让我们更有创意,而且,我认为,提高可读性。

因此,我们不会评估每个casetrue还是false;我们正在比较case的值是否等于我们的switch项。因此,让我们通过在我们的if语句中添加简写case并在条件为真的时返回原始切换项来利用它。

我还包括一个真实世界的例子,你想要有两个“默认值” - 如果你的术语在正面方向上超出你的“重要”范围,那么就是一个,如果你是在负面方向。

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

“如果我的字词x大于零,请返回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 :(得分:3)

首先,这不是switch的工作方式。您必须为每个case指定常量,并将这些常量与括号中的表达式进行比较(在您的情况下为amount)。这就是switch的工作方式,期间。

其次,切换速度不比几个if

第三,当你处理javascript时,你不应该真的担心微不足道的性能优化。

答案 4 :(得分:1)

问题是switch表达式不能等于case表达式,因为case表达式将计算为true或false,但switch表达式将是一个数字。

switch表达式设置为true的解决方案不起作用,因为true是常量,但因为实际上可以与case表达式进行相等。

您必须为每个案例表达式指定常量,这是不正确的。

要备份我的答案,请参阅Douglas Crockford,Javascript The Good Parts(2008),第12页:

  

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

答案 5 :(得分:1)

您还可以尝试我最喜欢的构造之一:

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)

好吧,你可以在case语句中使用表达式,这就是你的开关不是语法错误的原因。但您必须了解使用===(严格比较)比较 Case Clause 。理解了这一点后,该值必须与switch(expression)中的表达式值完全匹配,您可以在js中购买表达式。

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

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。

答案 7 :(得分:0)

我的2美分:

理想情况下,switch(作为一个原则)应该评估单个案例分支,从而实现O(1)性能和(除了通过案例),case语句可以以任何方式重新排序,而无需更改编译器分支策略。 / p>

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

编译器(除了可以智能地说出开发人员正在尝试做什么的编译器之外)将无法静态地优化分支策略,从而失去其有效性。

示例:

var x = 6, factors = [];

switch(x){

    case (x%2 == 0): factors.push(2);
    break;

    case (x%3 == 0): factors.push(3);
    break;
    ....
 }

{期待评论不良代码}

在上面的例子中,编译器没有实际的静态优化方法,因此没有其他方面的性能优势。

唯一的一部分是,它“可能”对开发人员来说看起来更干净,但如果出现其他情况,可能会导致中断。