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

时间:2015-03-03 10:32:19

标签: javascript switch-statement

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

switch (value) {

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

    case 2:
        doSomethingElse();
        break;

    default:
        break;

}

事实证明,这是完全合法的JavaScript。甚至没有标准的代码质量工具在这里抱怨:JSHint和JSCS对重复的标签,缺少的break语句和第二个案例2之后的死代码都很好。

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

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

1 个答案:

答案 0 :(得分:6)

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

除非引用Brendan Eich在某个地方解决这一特定问题(我还没有看到他这样做,但也许他有),我们无法肯定地说,我们只能想到< em>可能的原因。

我能想到两个:

  1. JavaScript的switch语句与C ++或Java的完全不同:case的值是表达式在运行时评估。在JavaScript中,switch实际上只是if/else if/else的语法糖(并且case被认为是源代码顺序,没有跳转表或类似的禁止优化步骤)。考虑这个有效的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;
    }
    

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

    由于他们在运行时评估了表达式,因此在一般情况下 提前知道他们是否重复(尽管您当然可以在特定情况下使用例如,因为值是常量)。

  2. JavaScript传统上没有编译步骤,并且传统上对编码奇怪事项很友好。一般来说,JavaScript中的方向是引擎应尽力运行他们所能提供的内容,而不是失败。这就是为什么在同一范围内两次使用var a;并不是bug,在同一范围内通过函数声明声明两个函数isn&#39; ta bug(第二个声明获胜)等等。