【问题标题】:is switch(true) {... valid javascript?是 switch(true) {... 有效的 javascript 吗?
【发布时间】:2012-12-16 15:21:27
【问题描述】:

我最近遇到了一个代码,其中 switch 语句似乎与 switch 中的答案(布尔值)和 case 中的表达式相反。代码按预期运行良好,但我担心跨浏览器。它是有效的javascript吗?

switch(true) {
  case (y < 20):
    //
    break;
  case (y < 60):
    //
    break;
  case (y < 130):
    //
    break;
}

【问题讨论】:

  • 我在 PHP 中也遇到过这个问题,并将其更改为 if/else if 块。在我看来,有人在这方面太聪明了,仅仅因为你可以并不意味着你应该这样做。但各有千秋。

标签: javascript boolean switch-statement


【解决方案1】:

这个 sn-p 非常好。这只是另一种表达方式:

if (y < 20) {
    // ...
} else if (y < 60) {
    // ...
} else if ( y < 130) {
    // ...
}

【讨论】:

  • 我会用if (true == (y &lt; 20)) 等来表达等效性,以显示开关真正在做什么。例如,如果它是switch(false),它将等同于if (false == (y &lt; 20)),并产生不同的结果。
  • @pst 我写的是“另一种表达方式”而不是“完全等同于”。
  • 因此我写了“我会用”而不是“那是错误的”来表达[它]——不要把评论当作一件坏事。 (虽然我的评论错了;使用===语义而不是==
  • s/elseif/else if/elseif 是 PHP,不是 JS。 :)
【解决方案2】:

是的,它是有效的。

与许多“现代”语言一样,Javascript 中的 switch 与 C 语言中基于 int 的 switch 相差甚远,它只保留了一般语义。

在 ECMAScript 中规范化的 switch 子句在此处详细解释:http://www.ecma-international.org/ecma-262/5.1/#sec-12.11

基本上,第一个值等于switch(Expression) 中的表达式的case 会被执行。

与明显的if else if 序列相比的主要优势是能够省略break 语句并执行多个块。请注意,与旧的 C 开关相反,没有真正的性能改进,在这种情况下,它既不简洁也不可读。

【讨论】:

  • 我不能 100% 确定 JavaScript,但 As in many "modern" languages 部分不正确。大多数编译的应用程序要求 case 值是一个常量,即可以在编译时进行评估。
  • 我说的不是常量而是int。示例:java(现在接受字符串)、Go(已编译)、Ruby。
  • 让我们也添加 C#。在 Go 中,case 子句根本不必是常量。
  • 在 C# 中,大小写必须是一个常量值。我很确定java是一样的。其余的,我不会说两种语言很多。
  • 我从来没有说过它们不应该是常量...请在评论之前阅读您评论的答案。
【解决方案3】:

syntax of switch statement 是:

SwitchStatement :  
  switch ( Expression ) CaseBlock  
CaseBlock :  
  { CaseClauses(opt) }  
  { CaseClauses(opt) DefaultClause CaseClauses(opt) }  
CaseClauses :  
  CaseClause  
  CaseClauses CaseClause  
CaseClause :  
  case Expression : StatementList(opt)  
DefaultClause :  
  default : StatementList(opt)

没有说 switch 表达式或 case 表达式必须是数字、字符串、布尔值或任何东西。 true 作为 switch 表达式是完全可以接受的,y &lt; 20 作为 case 表达式是完全可以接受的。请记住,switch 表达式和 case 表达式之间的比较是使用 === 运算符进行的。

在您发布的代码中,将执行第一个 true 案例,直到遇到 break 或 switch 块结束。

【讨论】:

    【解决方案4】:

    案例将根据y的值执行。

    因为条件取决于y 的值。正如aefxx所说,它是另一种形式:

    if (y < 20) {
        // ...
    } elseif (y < 60) {
        // ...
    } elseif ( y < 130) {
        // ...
    }
    

    【讨论】:

    • 不,这是不正确的。第一个break会跳到switch的末尾!
    • @bukfixart 更新了答案。案例根据 y 执行!
    • @bukart 实际上,没有。第一个中断需要在实际执行的 case 块内。 break 是仅在您实际击中它时才适用的语句。因此,如果 x>=y,您现在可以说 if (x&lt;y) break;,中断将永远不会产生任何影响。
    【解决方案5】:

    有效。

    代码

    switch(f0()) {
        case f1(): ..; 
        case f2(): ..;
        default: dflt;
    }
    

    其中fX()表示任意表达式(函数调用用于显示强制求值)可以近似重写为

    for (;;) { // for "break"
        var _x = f0()
        if (_x === f1()) { .. }
        if (_x === f2()) { .. }
        dflt;
        break;
    }
    

    case 中的表达式进行求值,然后与switch 中的表达式进行比较。 (这与需要 case 表达式中的常量值的 C 或 Java 等语言截然不同。)

    当然,break 将“退出开关”——与标准的贯穿语义相反——因此,true 是提供给switch 的表达式,发布的示例在语义上是等价的到if/else if,如aefxx所示。

    【讨论】:

      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 2018-01-06
      • 2016-01-21
      • 2018-10-21
      相关资源
      最近更新 更多