javascript:在切换情况下使用条件


88

很抱歉那个愚蠢的问题。如何在javascript切换案例语言元素中为案例使用条件?像下面的示例一样,当变量liCount<= 5和> 0时,大小写应该匹配;但是,我的代码不起作用:

switch (liCount) {
    case 0:
        setLayoutState('start');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case (liCount<=5 && liCount>0):
        setLayoutState('upload1Row');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case (liCount<=10 && liCount>5):
        setLayoutState('upload2Rows');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case (liCount>10):
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;                  
}

感谢您的任何建议!


4
使用if语句,而不是如果u想要做..
纳夫塔利又名尼尔

3
您不应忽略每个告诉您使用ifs的人,因为它们是正确的。这是的可怕应用switch
lincolnk 2014年

我不敢相信还没有提供这种解决方案。您可以执行此操作,该语句仅需要评估为switch子句中的值。这样就可以了:var liCount = 2; switch (liCount) { case 0: console.log(0); break; case (liCount<=5 && liCount>0) && liCount: console.log('liCount<=5 && liCount>0'); break; case (liCount<=10 && liCount>5) && liCount: console.log('liCount<=10 && liCount>5'); break; case (liCount>10) && liCount: console.log(liCount); break; }
Noitidart '16

Answers:


285

这有效:

switch (true) {
    case liCount == 0:
        setLayoutState('start');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case liCount<=5 && liCount>0:
        setLayoutState('upload1Row');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case liCount<=10 && liCount>5:
        setLayoutState('upload2Rows');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case liCount>10:
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;                  
}

此答案的先前版本认为括号是罪魁祸首。实际上,括号在这里是无关紧要的-唯一必要的是,switch(true){...}并且对于您的case表达式,其值必须为布尔值。

之所以起作用,是因为我们将给开关的值用作比较的依据。因此,同样对布尔值求值的case表达式将确定运行哪个case。也可以解决这个问题,传递switch(false){..}并让期望的表达式评估为false而不是true。但是个人更喜欢处理评估为真实的条件。但是,它也确实起作用,因此值得牢记以了解它在做什么。

例如:如果liCount为3,则第一个比较为true === (liCount == 0),表示第一种情况为假。然后,开关继续进行下一种情况true === (liCount<=5 && liCount>0)。该表达式的计算结果为true,表示此情况已运行,并在处终止break。我在此处添加了括号以使其更清楚,但它们是可选的,具体取决于表达式的复杂性。

这很简单,并且以一种整洁的方式(如果适合您要执行的操作)来处理一系列条件,其中一系列ìf() ... else if() ... else if () ...可能会引入大量视觉噪声或脆弱性。

请谨慎使用,因为尽管它是有效的代码,但它是非标准模式。


9
我认为您需要拥有switch(true) {case liCount == 0:对吗?否则,此比较为liCount == (liCount <=5 && liCount > 0)
loganfsmyth,2012年

33
你知道,这是不是因为你可以,你应该。这是需要用火杀死的东西。
JBert 2014年

21
它是语言的一部分-因此,了解它总比没有好。显然,这并不适合每种情况,但从纯粹主观的角度来看,我认为这是一种有趣的方法,比起一系列if / elifs,它更易读/不易碎。要记住的重要一点是,编码是意图的表达,是品味和实践的结合。有更多选择清楚地表达自己的想法,从来都不是一件坏事。
dmp

1
对我来说,这是一种非常有用的方法,也是一种很好的组织逻辑的方式,在这种情况下,我需要根据if条件反复使用变量名,但这是一个n + 1类型的情况,因此switch语句不包含条件中断将移至下面的下一行非常有用。
约瑟夫·阿斯特拉罕

2
您甚至睁开眼睛看看,如果switch表达式为false,结果将是这样 switch(false) { }
bello hargbola

24

的方式过于复杂这一点。用if语句编写它,如下所示:

if(liCount == 0)
    setLayoutState('start');
else if(liCount<=5)
    setLayoutState('upload1Row');
else if(liCount<=10)
    setLayoutState('upload2Rows');

$('#UploadList').data('jsp').reinitialise();

或者,如果ChaosPandion尝试尽可能优化:

setLayoutState(liCount == 0 ? 'start' :
               liCount <= 5 ? 'upload1Row' :
               liCount <= 10 ? 'upload2Rows' :
               null);

$('#UploadList').data('jsp').reinitialise();

你必须走了,扶我起来。:)
ChaosPandion 2011年

我们同时写了帖子。在发布之前,我看不到您的。您现在看来似乎过分了……
Eric

哇,我真的没有考虑过分复杂的条件。
ChaosPandion 2011年

1
@混沌:是的,那可能太过分了。您还必须向setLayoutState:P添加一个空检查。
埃里克(Eric)

@Eric-一些程序员比我要说的要花更多的时间:“仅仅因为您可以不用花括号就可以编写Java脚本(而且-实际上要小心-分号)并不意味着您应该这样做”,但是我只是重写了一些倍数无论如何,如您示例中的if语句,因此,谢谢-可以很好地工作,直到在条件之后要执行多行为止。三元解决方案对我来说是一座桥梁,但是……
Dave Everitt

7

您要使用if语句:

if (liCount === 0) {
    setLayoutState('start');
} else if (liCount <= 5) {
    setLayoutState('upload1Row');
} else if (liCount <= 10) {
    setLayoutState('upload2Rows');
}
$('#UploadList').data('jsp').reinitialise();  

7

请参阅下面的dmp答案。如果可以的话,我会删除这个答案,但是它被接受了,所以这是下一件好事:)

你不能 JS解释器要求您与switch语句进行比较(例如,不存在“ case when”语句)。如果您确实想这样做,则可以制作if(){ .. } else if(){ .. }块。


9
那是不对的。这是一个演示其工作原理的演示:jsfiddle.net/Ender/fr3wL。ECMAScript标准明确声明允许这样做:docstore.mik.ua/orelly/webprog/jscript/ch06_05.htm#FOOTNOTE-18
Ender

3
@Ender和haemse试图做的一样吗?
爱斯蒂娜(Aistina)2012年

@Aistina不是。由于他的案情产生的是真/假值而不是数字值,所以haemse将需要测试他的案子的真值(例如danp的答案所建议的),而不是针对的数值进行测试liCount。我只是指出cwolves最初的陈述“ JS解释器要求case陈述为静态值”是不正确的。此后cwolves修改了此声明,因此我的评论不再相关。
2012年

因为这不能回答问题。他并没有要求采用其他方式,而是要求使开关盒按自己的意愿工作。尽管我们几乎总是以为“用其他方式做”几乎从来都不是正确的答案。我们一直认为我们有更好的方法,但这不是他想要的方法,这使得答案完全是错误的。
茉莉花

@Jasmine-“您不能,因此可以通过其他方式进行”是正确的,如果它是正确的。我的回答被否决了,因为它是错误的:)正如@danp所指出的,您可以直接切换true就可以了。但是它已经3年多了,所以我真的不在乎。
马克·卡恩

5
switch (true) {
  case condition0:
    ...
    break;
  case condition1:
    ...
    break;
}

只要您的条件返回正确的boolean值,它就可以在JavaScript中工作,但是与else if语句相比并没有很多优势。


如果我10在switch语句中传递一些整数说会有效吗?在我的情况下无法正常工作,不知道是什么原因。
Pardeep Jain

10 !== true, 所以不行。是否存在一些可能具有该值的变量10?如果为x,则case x === 10:可以工作。
Mike Samuel

但是它应该像其他语句一样工作,例如,如果您使用if (10) {..}流应该传递If条件,不是吗?因为10或除0以外的任何整数将被视为真实值并允许输入条件。不知道他在这里切换语句出了什么问题。
Pardeep Jain

1
@PardeepJain,switch根本无法正常工作ifif测试条件是否真实switch试验后的表达式是否switch===CaseClauseIsSelected步骤4),以之后的表达式的值case
Mike Samuel

哦,那样,谢谢。这对我来说是全新的。@Mike
Pardeep Jain


4

如果那是您要执行的操作,则最好使用if语句。例如:

if(liCount == 0){
    setLayoutState('start');
}
if(liCount<=5 && liCount>0){
    setLayoutState('upload1Row');
}
if(liCount<=10 && liCount>5){
    setLayoutState('upload2Rows');
}             
var api = $('#UploadList').data('jsp');
    api.reinitialise();

2

您的代码无法正常工作,因为它没有按照您的期望进行操作。开关块采用一个值,并将每种情况与给定值进行比较,以寻找相等性。您的比较值是一个整数,但大多数情况下的表达式都解析为布尔值。

因此,例如说liCount = 2。您的第一种情况不匹配,因为2 != 0。您的第二种情况的(liCount<=5 && liCount>0)计算结果为true,但是2 != true,因此该情况​​也不匹配。

因此,正如许多其他人所说,您应该使用一系列if...then...else if块来执行此操作。


2

如果可能的值是整数,则可以组合大小写。否则,使用ifs。

var api, tem;

switch(liCount){
    case 0:
    tem= 'start';
    break;
    case 1: case 2: case 3: case 4: case 5:
    tem= 'upload1Row';
    break;
    case 6: case 7: case 8: case 9: case 10:
    tem= 'upload2Rows';
    break;
    default:
    break;
}
if(tem) setLayoutState((tem);
api= $('#UploadList').data('jsp');
api.reinitialise();

0

请注意,我们没有将分数传递给开关,而是传递给您。我们提供给开关的值用作比较的基础。

以下示例说明了如何在这种情况下添加条件:不带任何if语句。

function getGrade(score) {
    let grade;
    // Write your code here
    switch(true) {
        case score >= 0 && score <= 5:
        grade = 'F';
        break;
        case score > 5 && score <= 10:
        grade = 'E';
        break;
        case score > 10 && score <= 15:
        grade = 'D';
        break;
        case score > 15 && score <= 20:
        grade = 'C';
        break;
        case score > 20 && score <= 25:
        grade = 'B';
        break;
        case score > 25 && score <= 30:
        grade = 'A';
        break;
    }

    return grade;
}

0

尽管在OP的问题的特定示例中switch不合适,但是有一个示例仍然是适当/有益的,但是还需要其他评估表达式。这可以通过对表达式使用default子句来实现:

switch (foo) {
  case 'bar':
    // do something
    break;
  case 'foo':
    // do something
    break;
  ... // other plain comparison cases
  default:
    if (foo.length > 16) {
      // something specific
    } else if (foo.length < 2) {
      // maybe error
    } else {
      // default action for everything else
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.