JavaScript中带有逻辑运算符的switch语句?

69
for (var count = 1; count < 6; count++) {
    switch (count) {
        case (2):   document.write("hi"); break;     
        case (count > 3):   document.write("bye"); break;    
        case (count >= 4): document.write("lol"); break;
    }
}

因为它没有按我预期的工作,没有打印bye和lol,这让我觉得它在JavaScript中是无效的。我试图在Google上查找一些示例来看看其他人是否这样做,但并没有找到。那么这是有效的还是无效的?或者为什么它可能不起作用?

5个回答

152

当解释执行 switch 语句时,会将圆括号中的表达式与特定 case 的值进行比较。

因此,在您的情况下,count 的值将与 2count > 3count >= 4 的值进行比较。 这样是行不通的。 尽管您可以重写比较运算符来与 true 进行比较以使其正常工作:

switch (true) {
    case (count == 2):
        document.write("hi");
        break;
    case (count > 3):
        document.write("bye");
        break;
    case (count >= 4):
        document.write("lol");
        break;
}

但这不是 switch 语句的正确用法。

应该使用 if 语句代替:

if (count == 2) {
    document.write("hi");
} else if (count > 3) {
    document.write("bye");
} else if (count >= 4) {
    document.write("lol");
}
编辑:由于您仅使用switch的case(如果匹配则break),因此我的switch-if/else翻译是正确的。 但是count >= 4的情况/分支将永远不会应用,因为count > 3也对大于或等于4的count值成立。
要解决此问题(写入大于或等于4的值的“bye”和“lol”),请删除最后一个else,使最后一个if语句独立于前面的语句。
if (count == 2) {
    document.write("hi");
} else if (count > 3) {
    document.write("bye");
}
if (count >= 4) {
    document.write("lol");
}

@Doug:去掉最后一个“else”,它就可以了。 - Gumbo
在 switch 和 if 语句中,求值顺序仍然存在问题。请参见我的下面评论:https://dev59.com/pXE95IYBdhLWcg3wbtbO#3282442 - Dan Breslau

16

这是对Gumbo的回答的更正。我写了一个独立的回答,只是因为这不能作为评论。

编辑:Gumbo在评论中建议我可能误读了Doug的意图。如果原始帖子确实希望在计数 >= 4 时打印出 "bye" 和 "lol",那么我们需要从 switch 语句中移除一个 break。现在,案例恢复到原始顺序,以便按照"bye"和"lol"的顺序打印(这显然是原始帖子的意图。)

switch (true) {
    case (count == 2):
        document.write("hi");
        break;
    case (count > 3):
        document.write("bye");
        // No break here; just fall through.
    case (count >= 4):
        document.write("lol");
        break;
}

在这种情况下,我同意Gumbo的修改后的if语句是正确的。 原始答案如下(假设OP确实希望打印"lol"或"bye"中的一个,但不是两者都打印。) Gumbo编写的switch语句对于count >= 4是行不通的,与Gumbo的原始if语句的原因相同:因为按顺序评估案例,count >= 4意味着将执行第二个案例(count > 3);因此脚本永远不会达到count >= 4的测试。要解决此问题,应该按相反的顺序执行测试,从高到低:
switch (true) {
    case (count >= 4):
        document.write("lol");
        break;
    case (count > 3):
        document.write("bye");
        break;
    case (count == 2):
        document.write("hi");
        break;
}

经过修改的 if 语句仍然不正确,因为对于 count >= 4,它将在输出中产生 两个 代码行: byelol。再次强调,if 梯形内的测试应按从高到低的顺序排列:

if (count >= 4) {
    document.write("lol");
} else if (count > 3) {
    document.write("bye"); 
} else if (count == 2) {
    document.write("hi");
}

这不是一个理想的例子,因为如果count是一个整数,那么评估count >= 4count > 3将产生相同的结果--对于count >= 4false的情况除外。 如果count是浮点值,则情况就会有所不同(但是,命名为“count”的浮点值会引起其他问题)。


Doug没有给出他期望的结果的精确描述(“打印bye和lol”不是精确描述)。这就是为什么我只写了一个可行的switch示例和一个等效的if-else示例。 - Gumbo
你知道吗,我错过了这一点:我们都被硬编码为在每个case子句中包含一个break;我没有意识到OP 想要两种情况都执行。我将更新我的答案以涵盖这种情况。 - Dan Breslau

2

您使用了错误的case子句。您应该提供将与switch子句中的值进行比较的值...而不是像这样的布尔表达式count>2

在这种情况下,此布尔表达式将被转换为true或false(1或0),并与您的值计数进行比较,有时可能有效,有时则无效。

您应该考虑将其替换为if语句。


2

switch 通常需要一个固定的条件/值;因为你的 count 变量每次都会改变,这与之相悖。请改用 if-else 条件。


0

你应该交换最后两个情况。


@anthares:这还不足以让它正常工作,但这是一个错误,会阻止它按照他的期望工作。 - brian
看我的回答,你不能在case语句中放置布尔表达式...它不会按照你期望的那样被评估。它将与计数变量进行比较。 @user210118即使交换最后两个case也会阻止按照OP所期望的方式工作。 - anthares
@doug:> 3会捕捉到本应该属于>= 4的情况。 - brian
@anthares:你没有理解重点。是的,我们意识到他的代码存在问题,但一旦他按照你和其他人所概述的方式解决了这个问题,他需要交换最后两个case语句,因为现在它们的排列方式不会输出“lol”。 - brian
即使他交换了,它仍然不会工作...我知道这种情况是无法到达的,但用另一个错误的代码来纠正错误的代码有什么意义呢...你的答案不是解决方案。 - anthares

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接