在 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) 的语法。