在 CoffeeScript 指南的 switch 语句说明中,指明了
Switch statements can also be used without a control expression, turning them in to a cleaner alternative to if/else chains.
score = 76 grade = switch when score < 60 then 'F' when score < 70 then 'D' when score < 80 then 'C' when score < 90 then 'B' else 'A' # grade == 'C'
该 CoffeeScript 源码编译成 JavaScript 后如下:
var grade, score; score = 76; grade = (function() { switch (false) { case !(score < 60): return 'F'; case !(score < 70): return 'D'; case !(score < 80): return 'C'; case !(score < 90): return 'B'; default: return 'A'; } })();
这里有一个疑问:为什么要使用 switch (false)
作为判断条件,并将 case
条件全部取非运算。为什么不直接使用 switch (true)
且直接传入 case
条件。即编译成:
var grade, score;
score = 76;
grade = (function() {
switch (true) {
case (score < 60):
return 'F';
case (score < 70):
return 'D';
case (score < 80):
return 'C';
case (score < 90):
return 'B';
default:
return 'A';
}
})();
无论是可读性还是代码尺寸都比前者高。
产生该疑问的原因是对 JavaScript 的 switch 语法不了解。MDN 中对 switch 语句的描述中,特别指明了:
The program first looks for a case clause whose expression evaluates to the same value as the input expression (using strict comparison, ===) and then transfers control to that clause, executing the associated statements.
即 switch 语句使用严格相等(===
)来进行 case 的比较,如果使用 switch(true)
的方式,一旦用户在 case 中传入的不是返回 boolean 的表达式,则永远不会匹配上。此时符合语义的 case 语法应该是
case Boolean(score < 60):
或
case !!(score < 60):
此时虽然提高了可读性,但是(在 case 数大于1时)代码体积反而比 switch (true)
大。考虑到可读性不是编译后 JavaScript 的主要关注点,CoffeeScript 编译器最终采用了 switch (false)
的语法。