为什么在JavaScript中允许交换机块中重复的案例标签?

GOT*_*O 0 3 javascript switch-statement

我在调试的文件中发现了一个令人讨厌的复制粘贴错误.它是switch声明中的重复案例标签.

switch (value) {

    case 1:
    case 2:
        doSomething();
        break;

    case 2:
        doSomethingElse();
        break;

    default:
        break;

}
Run Code Online (Sandbox Code Playgroud)

事实证明,这是完全合法的JavaScript.甚至标准的代码质量工具也没有在这里抱怨:JSHint和JSCS对于重复标签,缺少的break语句和第二种情况2之后的死代码都没问题.

据我所知,重复的案例值在C++和Java中是非法的.

JavaScript中的交换机块中是否有多个相同的案例标签?为什么允许这样做?

T.J*_*der 6

当然,根本的答案是,因为规范并没有说它是无效的.但这只是引出了为什么规范没有说它无效的问题.

除非引用Brendan Eich在某处解决这一具体问题(我没有看到他这样做,但也许他有),我们不能肯定地说,我们只能想到可能的原因.

我能想到两个:

  1. JavaScript的switch陈述与C++或Java完全不同:cases 的值是在运行时计算的表达式.switch在JavaScript中,它实际上只是语法糖if/else if/else(并且cases被认为是源代码顺序,没有跳转表或类似的限制优化步骤).考虑这个有效的JavaScript:

    var a = "foo";
    var b = "bar";
    var c = Math.random() < 0.5 ? "FOO" : "BAR";
    
    switch (c) {
      case a.toUpperCase():
        console.log("It was " + a + " in upper case");
        break;
      case b.toUpperCase():
        console.log("It was " + b + " in upper case");
        break;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    你不能用C++或Java做到这一点.

    由于它们是在运行时评估的表达式,因此在一般情况下你不能事先知道它们是重复的(当然你可以在你的具体例子中,因为值是常量).

  2. JavaScript传统上没有编译步骤,传统上对编码奇怪的编码很友好.一般来说,JavaScript中的方向是引擎应该尽可能地运行它们所能给出的内容,而不是失败.这就是为什么var a;在同一范围内使用两次不是bug,在同一范围内通过函数声明声明两个函数不是错误(第二个声明获胜)等.