Javascript switch case 语句中的表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3463833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:44:20  来源:igfitidea点击:

Expression inside switch case statement

javascriptswitch-statementcase

提问by Marko

I'm trying to create a switch statement but I can't seem to be able to use an expression that gets evaluated (rather than a set string/integer). I can easily do this with if statements but case should hopefully be faster.

我正在尝试创建一个 switch 语句,但我似乎无法使用被评估的表达式(而不是一组字符串/整数)。我可以用 if 语句轻松地做到这一点,但 case 应该会更快。

I'm trying the following

我正在尝试以下

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;
    }
}

Am i missing something obvious or is this not possible? Google hasn't been friendly in this case.

我错过了一些明显的东西还是这是不可能的?在这种情况下,谷歌并不友好。

Any help/pointers appreciated

任何帮助/指针表示赞赏

M

回答by MooGoo

You could always do

你总能做到

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

  //etc...

It works because trueis a constant, so the code under the first case statement with an expression that evaluates to true will be executed.

它之所以有效,true是因为它是一个常量,因此将执行第一个 case 语句下的代码,其表达式为真。

It's kinda "tricky" I guess, but I see nothing wrong with using it. A simple if/elsestatement would probably be more concise, and you'd not have to worry about accidental fall-through. But there it is anyway.

我想这有点“棘手”,但我认为使用它没有任何问题。一个简单的if/else语句可能会更简洁,您不必担心意外落空。但无论如何它就在那里。

回答by ruffin

@MooGoo's switch (true)will give you a Weird conditionerror in jsLint, so let's get a little more creative in case that's an issue, and, I think, increase readability a touch.

@MooGoo'sswitch (true)Weird condition在 jsLint 中给你一个错误,所以让我们更有创意,以防万一这是一个问题,我认为,增加可读性。

So we're not evaluating if each caseis trueor false; we're comparing if that case's value is equal to our switchterm. So let's take advantage of that by throwing a shorthand ifinto our casestatement and return our original switch term if the condition's true.

所以我们不评估每个casetruefalse;我们正在比较它case的值是否等于我们的switch术语。所以让我们利用这一点,if在我们的case语句中加入一个速记,如果条件为真,则返回我们原来的 switch 项

I'm also including a sort of real world example, where you want to have two "defaults" -- one if your term is outside of your "important" range in the positive direction, and another in case you're in the negative direction.

我还包括了一种现实世界的例子,你想要有两个“默认值”——一个如果你的术语在积极的方向上超出你的“重要”范围,另一个如果你处于负面方向。

Key phrase: case (x > 0 ? x : null):

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

"If my term, x, is greater than zero, return xso that x === xand I take the case branch."

“如果我的术语 ,x大于零,则返回xx === x然后我采用 case 分支。”

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

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.');

回答by Daniel A. White

That is not how a switchblock works. The caseis used to hold a single value that if they are equal to the value on the switchline. if-elsestatements will serve you well.

这不是switch块的工作方式。所述case用于保持一个单一的值,如果它们是相等的值switch线。if-else声明将很好地为您服务。

Here is some information about the switchblock.

以下是有关该switch块的一些信息。

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

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

回答by Fyodor Soikin

Firstly, that's not how switchworks. You have to specify constants for each case, and those constants will be compared to the expression in parentheses (in your case, amount). That is how switchworks, period.

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

Secondly, switch is not faster than several ifs

其次,开关不超过几个快if小号

And thirdly, you shouldn't really worry about miniscule performance optimizations when you're dealing with javascript.

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

回答by robert

You could also try one of my favorite constructions:

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

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"
    );
}

回答by dotnetCarpenter

Well, you can have expressions in casestatement which is why your switch is not a syntax error. But you have to understand that the Case Clauseis compared using === (strict comparison). Once you understand this, that the value must match exactly with the expression value in your switch(expression)you can shop around for expressions in js.

好吧,您可以在case语句中使用表达式,这就是为什么您的 switch 不是语法错误的原因。但是您必须了解Case 子句是使用 ===(严格比较)进行比较的。一旦你理解了这一点,该值必须与你的表达式值完全匹配,switch(expression)你可以在 js 中寻找表达式。

Function calls are expressions, so let's try with them:

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

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

As you can see, you can both use function expressions and function definitions. It doesn't matter. Only that the expression in the case clause is an expression to evaluate. Which is the same as you did, only you did not return a value that was the same as the amount but rather a true or false value. In my example I return the exact amount if my condition is true, hence trigger the comparison to match.

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

Here is your fixed code:

这是您的固定代码:

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;
    }
}

Here is the specification: https://tc39.github.io/ecma262/#sec-switch-statementThe link is to es2016 because it's easier to lookup than the old es3 pdf from 1999. But it has always worked like this, but it is a little known fact.

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

I however doubt that this is faster than ifstatements. If you want your run to run fast, then do nottouch the DOM.

然而,我怀疑这比if陈述更快。如果你想让你的跑步跑得快,那么不要接触 DOM。

回答by Jon Lyles

The problem is the switch expression cannot ever equal the case expressions, because the case expression will evaluate to true or false, but the switch expression will be a number.

问题是 switch 表达式永远不能等于 case 表达式,因为 case 表达式的计算结果为真或假,但 switch 表达式将是一个数字。

The solution where the switch expression is set to true works not because true is a constant but because equality with the case expressions is actually possible.

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

It's not true that you have to specify constants for each case expression.

您必须为每个 case 表达式指定常量是不正确的。

To back up my answer, refer to Douglas Crockford, Javascript The Good Parts (2008), page 12:

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

The switch statement performs a multiway branch. It compares the expression for equality with all the selected cases.... When an exact match is found, the statements of the matching case clause are executed... A case clause contains one or more case expressions. The case expressions need not be constants.

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

回答by GNM

My 2 cents:

我的 2 美分:

Ideally switch (as a principle) should evaluate to a single case branch , thereby achieving O(1) performance and (other than fall through cases) the case statements can be reordered in any way without changing the compiler branching strategy.

理想情况下, switch (原则上)应该评估单个 case branch ,从而实现 O(1) 性能,并且(除了落入 case)case 语句可以以任何方式重新排序,而无需更改编译器分支策略。

If expressions are used (assuming the language allows it), then theoretically, it can follow more than branch.

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

The compiler (other than those which can intelligently say what the developer is trying to do) will not be able to optimize the branching strategy statically and ideally thus losing its effectiveness.

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

Example:

例子:

var x = 6, factors = [];

switch(x){

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

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

{Expect comments on poor code}

{期待对糟糕代码的评论}

In the above example, there is no practical way for the compiler to statically optimize, thus gains no performance benefit over if else.

在上面的例子中,编译器没有实用的静态优化方法,因此与 if else 相比没有性能优势。

The only part is that, it "may" look cleaner to the developer but could in-effect be cause for disruption in case of additional conditions.

唯一的部分是,它“可能”对开发人员来说看起来更干净,但实际上可能会在其他条件下导致中断。