开关(true){…是有效的javascript吗?

开关(true){…是有效的javascript吗?,javascript,boolean,switch-statement,Javascript,Boolean,Switch Statement,我最近遇到一段代码,其中switch语句似乎与switch中的答案(布尔值)和case中的表达式相反。代码运行正常,但我担心跨浏览器。它是有效的javascript吗 switch(true) { case (y < 20): // break; case (y < 60): // break; case (y < 130): // break; } 开关(真){ 病例(y

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

switch(true) {
  case (y < 20):
    //
    break;
  case (y < 60):
    //
    break;
  case (y < 130):
    //
    break;
}
开关(真){
病例(y<20):
//
打破
病例(y<60):
//
打破
病例(y<130):
//
打破
}

这段代码非常好。这只是另一种表达方式:

if (y < 20) {
    // ...
} else if (y < 60) {
    // ...
} else if ( y < 130) {
    // ...
}
if(y<20){
// ...
}否则,如果(y<60){
// ...
}否则,如果(y<130){
// ...
}
是的,它是有效的

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

ECMAScript中规范化的switch子句在此处详细解释:

基本上,执行值等于
开关(表达式)
中表达式的第一种情况

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

案例将基于va执行
y的lue
。 因为条件取决于
y
的值。如所述,它是另一种形式:

if (y < 20) {
    // ...
} elseif (y < 60) {
    // ...
} elseif ( y < 130) {
    // ...
}
if(y<20){
// ...
}elseif(y<60){
// ...
}elseif(y<130){
// ...
}
它是有效的

代码

switch(f0()) {
    case f1(): ..; 
    case f2(): ..;
    default: dflt;
}
其中,
fX()
表示任意表达式(函数调用用于显示强制求值),可以近似地重新编写为

for (;;) { // for "break"
    var _x = f0()
    if (_x === f1()) { .. }
    if (_x === f2()) { .. }
    dflt;
    break;
}
也就是说,计算
案例
中的表达式,然后将其与
开关
中的表达式进行比较(这与
案例
表达式中需要常量值的C或Java等语言有很大区别。)

当然,
break
将“退出开关”-与标准的fall-through语义相反-因此,当
true
是提供给
switch
的表达式时,发布的示例在语义上等同于aefxx所示的
if/else if

SwitchStatement:
开关(表达式)CaseBlock
案例组:
{case子句(opt)}
{casetracles(opt)DefaultClause casetracles(opt)}
案例条款:
案例条款
案例条款案例条款
案例条款:
大小写表达式:语句列表(opt)
违约条款:
默认值:语句列表(opt)
没有说明开关表达式或大小写表达式必须是数字、字符串、布尔值或任何内容。
true
作为开关表达式完全可以接受,
y<20
作为大小写表达式完全可以接受。请记住,开关表达式和大小写表达式之间的比较是使用
===操作员


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

不,这是不正确的。第一个break将跳转到开关的末尾!@bukfixart更新了答案。案例根据y执行!@bukart实际上,不。第一个break需要在案例中实际执行的块。break是只在实际执行时才应用的语句。因此,可以说
如果(x=y),则break将永远不会有任何效果。我不是100%确定JavaScript,而是像许多“现代”中那样的
语言
部分不正确。大多数已编译的应用程序要求case值为常量,即可以在编译时计算。我没有提到常量,而是int。示例:java(现在接受字符串)、Go(已编译),Ruby。让我们再加上C#。在Go中,case子句根本不必是常量。在C#中,case必须是常量值。我非常确定java是一样的。对于其他语言,我不会说两种语言有很多种。我从来没有说过它们不应该是常量……请在评论之前阅读您评论的答案。我会用术语表达等价性例如,如果它是
switch(false)
,它将等价于
if(false==(y<20))
,并产生不同的结果。@pst我写了“另一种表达“not”的方式是完全等价的”。因此我写了“我会用而不是“那是错误的”-不要把评论看作是一件坏事。(虽然我的评论是错误的;
===
使用了语义,而不是
==
s/elseif/else如果/
elseif
是PHP,而不是JS.)我在PHP中也遇到了这个问题,并将其更改为if/else if块。在我看来,有些人在这方面太聪明了,仅仅因为你可以并不意味着你应该这样做。但每个人都有自己的想法。