开关(true){…是有效的javascript吗?
我最近遇到一段代码,其中switch语句似乎与switch中的答案(布尔值)和case中的表达式相反。代码运行正常,但我担心跨浏览器。它是有效的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(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块。在我看来,有些人在这方面太聪明了,仅仅因为你可以并不意味着你应该这样做。但每个人都有自己的想法。