我正在尝试创建一个switch语句,但我似乎无法使用得到评估的表达式(而不是设置字符串/整数)。我可以使用if语句轻松完成此操作,但希望案例更快。
我正在尝试以下
function reward(amount) {
var $reward = $("#reward");
switch (amount) {
case (amount >= 7500 && amount < 10000):
$reward.text("Play Station 3");
break;
case (amount >= 10000 && amount < 15000):
$reward.text("XBOX 360");
break;
case (amount >= 15000):
$reward.text("iMac");
break;
default:
$reward.text("No reward");
break;
}
}
我错过了一些明显的东西,或者这是不可能的?在这种情况下,谷歌并不友善。
任何帮助/指示赞赏
中号
答案 0 :(得分:98)
你可以随时
switch (true) {
case (amount >= 7500 && amount < 10000):
//code
break;
case (amount >= 10000 && amount < 15000):
//code
break;
//etc...
它的工作原理是因为true
是一个常量,所以第一个case语句下的代码将被执行。
我觉得这有点“棘手”,但我觉得使用它并没有错。一个简单的if/else
陈述可能会更简洁,你不必担心意外跌倒。但无论如何它仍然存在。
答案 1 :(得分:10)
这不是switch
块的工作原理。 case
用于保存单个值,如果它们等于switch
行上的值。 if-else
语句将很好地为您服务。
以下是有关switch
阻止的一些信息。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
答案 2 :(得分:10)
@ MooGoo的switch (true)
会给你一个Weird condition
error in jsLint,所以如果这是一个问题,让我们更有创意,而且,我认为,提高可读性。
因此,我们不会评估每个case
是true
还是false
;我们正在比较case
的值是否等于我们的switch
项。因此,让我们通过在我们的if
语句中添加简写case
并在条件为真的时返回原始切换项来利用它。
我还包括一个真实世界的例子,你想要有两个“默认值” - 如果你的术语在正面方向上超出你的“重要”范围,那么就是一个,如果你是在负面方向。
关键词:
case (x > 0 ? x : null):
“如果我的字词x
大于零,请返回x
,以便x === x
我接受案例分支。”
http://jsfiddle.net/rufwork/upGH6/1/
/*global document*/
/*jslint evil:true*/
var x = 10;
switch (x) {
case (x > 0 ? x : null):
document.write('ha ha ha! I fooled switch AND jsLint! Muhahahahaha!');
break;
case 0:
document.write('zero is nothing.');
break;
case -1:
document.write('low');
break;
case -2:
document.write('lower');
break;
case -3:
document.write('lowest I care about');
break;
default: // anything lower than -3.
document.write('TOO LOW!!!! (unless you cheated and didn\'t use an int)');
}
document.write('<br>done.');
答案 3 :(得分:3)
首先,这不是switch
的工作方式。您必须为每个case
指定常量,并将这些常量与括号中的表达式进行比较(在您的情况下为amount
)。这就是switch
的工作方式,期间。
其次,切换速度不比几个if
第三,当你处理javascript时,你不应该真的担心微不足道的性能优化。
答案 4 :(得分:1)
问题是switch表达式不能等于case表达式,因为case表达式将计算为true或false,但switch表达式将是一个数字。
switch表达式设置为true的解决方案不起作用,因为true是常量,但因为实际上可以与case表达式进行相等。
您必须为每个案例表达式指定常量,这是不正确的。
要备份我的答案,请参阅Douglas Crockford,Javascript The Good Parts(2008),第12页:
switch语句执行多路分支。它将相等的表达式与所有选定的情况进行比较....当找到完全匹配时,将执行匹配case子句的语句... case子句包含一个或多个case表达式。案例表达式不一定是常量。
答案 5 :(得分:1)
您还可以尝试我最喜欢的构造之一:
function reward(amount) {
var $reward = $("#reward");
$reward.text(
(amount >= 7500 && amount < 10000) ? "Play Station 3" :
(amount >= 10000 && amount < 15000)? "XBOX 360" :
(amount >= 15000) ? "iMac" :
"No reward"
);
}
答案 6 :(得分:1)
好吧,你可以在case
语句中使用表达式,这就是你的开关不是语法错误的原因。但您必须了解使用===(严格比较)比较 Case Clause 。理解了这一点后,该值必须与switch(expression)
中的表达式值完全匹配,您可以在js中购买表达式。
函数调用是表达式,所以让我们尝试一下:
function xbox(amount) { return amount >= 10000 && amount < 15000 && amount; }
function reward(amount) {
var ps3 = function(amount) { return amount >= 7500 && amount < 10000 && amount; }
function imac(amount) { return amount >= 15000 && amount; }
var $reward = $("#reward");
switch (amount) {
case ps3(amount):
$reward.text("Play Station 3");
break;
case xbox(amount):
$reward.text("XBOX 360");
break;
case imac(amount):
$reward.text("iMac");
break;
default:
$reward.text("No reward");
break;
}
}
reward(8200)// -> Play Station 3
reward(11000)// -> XBOX 360
reward(20000)// -> iMac
如您所见,您可以使用函数表达式和函数定义。没关系。只有case子句中的表达式才是要计算的表达式。这与您的相同,只是您没有返回与金额相同的值,而是返回真值或假值。在我的例子中,如果我的条件为真,我会返回确切的金额,因此触发比较以匹配。
这是您的固定代码:
function reward(amount) {
var $reward = $("#reward");
switch (amount) {
case (amount >= 7500 && amount < 10000 && amount):
$reward.text("Play Station 3");
break;
case (amount >= 10000 && amount < 15000 && amount):
$reward.text("XBOX 360");
break;
case (amount >= 15000 && amount):
$reward.text("iMac");
break;
default:
$reward.text("No reward");
break;
}
}
以下是规范:https://tc39.github.io/ecma262/#sec-switch-statement 链接是es2016,因为它比1999年的旧es3 pdf更容易查找。但它总是这样工作,但这是一个鲜为人知的事实。
但我怀疑这比if
陈述更快。如果您希望自己的运行速度很快,那么不要触摸DOM。
答案 7 :(得分:0)
我的2美分:
理想情况下,switch(作为一个原则)应该评估单个案例分支,从而实现O(1)性能和(除了通过案例),case语句可以以任何方式重新排序,而无需更改编译器分支策略。 / p>
如果使用表达式(假设语言允许),那么从理论上讲,它可以遵循多个分支。
编译器(除了可以智能地说出开发人员正在尝试做什么的编译器之外)将无法静态地优化分支策略,从而失去其有效性。
示例:
var x = 6, factors = [];
switch(x){
case (x%2 == 0): factors.push(2);
break;
case (x%3 == 0): factors.push(3);
break;
....
}
{期待评论不良代码}
在上面的例子中,编译器没有实际的静态优化方法,因此没有其他方面的性能优势。
唯一的一部分是,它“可能”对开发人员来说看起来更干净,但如果出现其他情况,可能会导致中断。