在 JavaScript 中打开整数范围

我想做这样的事

    switch (this.dealer) {
case 1-4:
// Do something.
break;
case 5-8:
// Do something.
break;
case 9-11:
// Do something.
break;
default:
break;
}

什么是正确的语法? 在 JavaScript 中可能吗?

所以 this.dealer是一个整数,如果它在这些值之间,那么做一些事情。

198137 次浏览
    switch(this.dealer) {
case 1:
case 2:
case 3:
case 4:
// Do something.
break;
case 5:
case 6:
case 7:
case 8:
// Do something.
break;
default:
break;
}

如果你不喜欢案件的连续性,只要去 if/else if/else陈述。

不,这不可能,最接近的就是:

  switch(this.dealer) {
case 1:
case 2:
case 3:
case 4:
// DO SOMETHING
break;
case 5:
case 6:
case 7:
case 8:
// DO SOMETHING
break;

但是这个非常笨拙。

对于这种情况,最好使用 if/else if结构。

如果您需要检查范围,那么使用 ifelse if语句可能更好,如下所示:

if (range > 0 && range < 5)
{
// ..
}
else if (range > 5 && range < 9)
{
// ..
}
else
{
// Fall through
}

开关可以在更大的范围内变得更大。

我想到了另一个办法:

const x = this.dealer;
switch (true) {
case (x < 5):
alert("less than five");
break;
case (x < 9):
alert("between 5 and 8");
break;
case (x < 12):
alert("between 9 and 11");
break;
default:
alert("none");
break;
}

MarvinLabs 给出了更清晰的答案:

var x = this.dealer;
switch (true) {
case (x < 5):
alert("less than five");
break;
case (x < 9):
alert("between 5 and 8");
break;
case (x < 12):
alert("between 9 and 11");
break;
default:
alert("none");
break;
}

没有必要检查范围的下端,因为 break语句将导致执行跳过剩余的情况,所以当执行到检查时,例如(x < 9)我们知道值必须是5或更大。

当然,只有当情况保持在原来的顺序时,输出才是正确的,我们假设整数值(如问题中所述)——从技术上讲,范围在5到8.9999999999999之间,因为 js 中的所有数字实际上都是双精度浮点数。

如果您希望能够移动大小写,或者希望在每个大小写语句中都能看到完整的大小写范围,那么只需要为每个大小写的较低范围添加一个小于或等于的检查:

var x = this.dealer;
switch (true) {
case (x < 5):
alert("less than five");
break;
case (x >= 5 && x < 9):
alert("between 5 and 8");
break;
case (x >= 9 && x < 12):
alert("between 9 and 11");
break;
default:
alert("none");
break;
}

请记住,这会增加额外的人为错误——有人可能试图更新一个范围,但忘记在两个地方都更改它,留下一个重叠或缺口,没有覆盖。例如,在这里的情况下,8现在将不匹配任何东西,当我只是编辑的情况下,用来匹配8。

    case (x >= 5 && x < 8):
alert("between 5 and 7");
break;
case (x >= 9 && x < 12):
alert("between 9 and 11");
break;

这个 不需要 switch 语句。它更清晰,更简洁,更快,更优化,使用 if else 语句..。

var d = this.dealer;
if (1 <= d && d <= 11) { // making sure in range 1..11
if (d <= 4) {
alert("1 to 4");
} else if (d <= 8) {
alert("5 to 8");
} else {
alert("9 to 11");
}
} else {
alert("not in range");
}

速度测试

我很好奇使用开关而不是简单的 if... else... 的开销,所以我把 jsFiddle 放在一起检查它..。 Http://jsfiddle.net/17x9w1el/

  • 铬: 开关如果还有别的慢70% 左右

  • Firefox: 开关如果还有别的慢5% 左右

  • 开关如果还有别的慢5% 左右

  • Safari: 开关如果还有别的慢95% 左右

备注:

赋值给局部变量是可选的,特别是如果您的代码稍后将被自动优化。

对于数值范围,我喜欢使用这种结构..。

if (1 <= d && d <= 11) {...}

... 因为对我来说,它读起来更接近于你在数学中表达一个范围(1 < = d < = 11) ,当我读代码的时候,我可以理解为“如果 d 在1和11之间”。

更清晰

有些人不认为这是清楚的。我想说,这并不是不清楚,因为结构是接近完全相同的开关选项。它 更清晰的主要原因是它的每一部分是可读的,并使简单的直观感觉。

我对“ switch (true)”的担心是,它可能看起来是一行毫无意义的代码。很多程序员,读到这里就不知道该怎么理解了。

对于我自己的代码,我更愿意时不时地使用模糊的结构,但是如果有人愿意看看,我会尝试使用更清晰的结构。我认为最好使用构造来实现它们的目的。

优化

在现代环境中,为了生产,代码通常会被缩小,因此您可以编写清晰简洁的代码,带有可读的变量名和有用的注释。没有明确的理由这样使用开关。

我还尝试将这两个构造放入一个缩小器中。If/else 结构压缩得很好,使用嵌套的三元运算符成为一个简短的表达式。当缩小时,switch 语句仍然是一个 switch,包含“ switch”、“ case”和“ break”令牌,因此代码中的时间要长得多。

开关(真)是如何工作的

我认为“开关(真)是模糊的,但似乎有些人只是想使用它,所以这里有一个解释为什么它的工作..。

Switch/case 语句的工作方式是将 switch 中的部分与每个 case 进行匹配,然后在第一次匹配时执行代码。在大多数情况下,我们在开关中有一个变量或非常量表达式,然后将其匹配。

使用“ switch (true) ,我们将发现 case 语句中的第一个表达式为 true。如果你把“ switch (true)”读作“ find the first expression that is true”,代码看起来更具可读性。

如果你想做一些快速、高效、易读的事情,使用一个标准的 If... then... else 结构,如下所示:

var d = this.dealer;
if (d < 12) {
if (d < 5) {
alert("less than five");
}else if (d < 9) {
alert("between 5 and 8");
}else{
alert("between 9 and 11");
}
}else{
alert("none");
}

如果你想混淆它,让它变得可怕(但是很小) ,试试这个:

var d=this.dealer;d<12?(d<5?alert("less than five"):d<9?alert("between 5 and 8"):alert("between 9 and 11")):alert("none");

顺便说一下,上面的代码是一个 JavaScript if... then... else 速记语句。这是一个很好的例子,说明如何不编写代码,除非混淆或代码缩小是目标。请注意,如果以这种方式编写代码,代码维护可能是一个问题。很少有人能够轻易地通读它,如果有的话。然而,代码大小比标准小50% ,如果... ... 那么... ... 否则不会有任何性能损失。这意味着在较大的代码库中,像这样的缩小可以极大地提高跨带宽受限或高延迟网络的代码传输速度。

然而,这不应该被认为是一个好的答案。这只是一个例子,什么可以做,而不是什么应该做。

更易读的三元组版本可能是这样的:

var x = this.dealer;
alert(t < 1 || t > 11
? 'none'
: t < 5
? 'less than five'
: t <= 8
? 'between 5 and 8'
: 'Between 9 and 11');