4

I found a nasty copy-paste bug in a file I was debugging. It's a duplicate case label in a switch statement.

switch (value) {

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

    case 2:
        doSomethingElse();
        break;

    default:
        break;

}

As it turns out, this is perfectly legal JavaScript. Not even the standard code quality tools complain here: JSHint and JSCS are fine with the repeated label, the missing break statement and the dead code after the second case 2.

To my knowledge, duplicate case values are illegal in C++ and Java.

Is there a purpose for having multiple identical case labels in a switch block in JavaScript? Why is this allowed?

Andy Fleming
  • 7,655
  • 6
  • 33
  • 53
GOTO 0
  • 42,323
  • 22
  • 125
  • 158
  • 2
    The second case will never be met. it is effectively dead code. I guess they just dont look for that because they expect programmers to not do such a silly thing – Tschallacka Mar 03 '15 at 10:35
  • 2
    Well, that question is like "why was JS designed that way?". I'm not sure what kind of answer you expect to hear. – freakish Mar 03 '15 at 10:35
  • 1
    Yes, it's a question about language design, thus subjective. ) And there are use-cases for that with fall-through behaviour ([here's one](http://stackoverflow.com/a/26026627/1229023)). – raina77ow Mar 03 '15 at 10:37
  • 1
    @raina77ow: AFAICT, the second `case 0:` in that example has exactly no purpose and could be removed. – T.J. Crowder Mar 03 '15 at 10:46
  • 2
    WebStorm (or other JetBrains editors) do show a warning when there is a duplicate case label. – Andy Fleming Mar 03 '15 at 10:46
  • 1
    @DesignerGuy: Yet another reason to use JetBrains editors. :-) – T.J. Crowder Mar 03 '15 at 10:47

1 Answers1

6

The fundamental answer is, of course, because the specification doesn't say it's invalid. But that just begs the question of why the specification doesn't say it's invalid.

Barring a citation for Brendan Eich addressing this specific point somewhere (I haven't seen him do it, but maybe he has), we can't say for sure, we can only try to think of possible reasons.

I can think of two:

  1. JavaScript's switch statement is quite different from C++'s or Java's: The values of the cases are expressions evaluated at runtime. switch, in JavaScript, is really just syntactic sugar for if/else if/else (and the cases are considered in source code order, no jump tables or similar barring an optimization step). Consider this valid 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;
    }
    

    You can't do that in C++ or Java.

    Since they're expressions evaluated at runtime, you can't in the general case know in advance that they're duplicates (although of course you could in your specific example, because the values are constants).

  2. JavaScript traditionally doesn't have a compilation step and is traditionally friendly to coding oddities. In general, the orientation in JavaScript is that engines should try their best to run what they're given if they can, rather than fail. This is why using var a; twice in the same scope isn't a bug, declaring two functions via function declarations in the same scope isn't a bug (the second declaration wins), etc.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875