Javascript: switch

2007-09-03

The switch statement in JavaScript is more or less borrowed from C. But unlike C where the case labels have to be constant expressions the case labels in JavaScript can be any expression.

I expect that they did this is so that, despite the fact that JavaScript has no notion of constant, you can go:

switch(node.type) {
  case Node.ELEMENT_NODE: blah blah
  case Node.ATTRIBUTE_NODE: blah blah
  case Node.TEXT_NODE: blah blah
}

rather than the less clear:

switch(node.type) {
  case 1: blah blah
  case 2: blah blah
  case 3: blah blah
}

(Though strangely, you see a lot of people referring to DOM enumeration values (like Node.ELEMENT_NODE) by their numeric value.)

Of course in C you’d use enumeration members because they’re constants and it would look much the same.

The fact that the case labels are general expressions is reminiscent of CASE/WHEN from BBC BASIC V (on the Archimedes) and I am reminded of a hackish abuse I was once told about: you put some constant expression in the switch, true say, and a bunch of variable expressions, a bunch of conditionals, in the case statements. Like this:

switch(true) {
  case a>b : blah blah
  case foo(bar)=='spong' : blah blah
  case isNaN(x) : blah blah
}

All day I’ve been trying to think of some reason why this might be remotely useful.

About these ads

9 Responses to “Javascript: switch”

  1. glorkspangle Says:

    Maybe people use the numeric values because it lets the compiler use the fact that they are constants?

  2. drj11 Says:

    Could be. The Javascript community seems to attract all sorts.

  3. Clive Says:

    Does Javascript require break in the way C/C++ does?

    If so, one meagre “advantage” of switch over “if … else if … else if … else” is that cases can follow through.

  4. drj11 Says:

    Yes, like C, JavaScript’s cases followthrough / require break. Though unlike C, the case clauses are not independent; they must appear as the direct children of the switch‘s caseblock and not, for example, embedded inside an interior while statement. Duff’s device is not possible in JavaScript. Hurrah!

    Even with the fallthrough behaviour (which I realised) I still couldn’t think of a really compelling abuse. The corresponding abuse in BASIC V saves some tokens compared to the ELSEIF chain when used on one line. IIRC.

    Aside: I’m glad Google groups has the original Tom Duff posting. Nice bit of history which is all too often told second hand.

  5. drj11 Says:

    On constant folding: Of course in the case where the Node.ELEMENT_NODE is the obvious element from the w3.org’s DOM then the compiler can rely on the fact that Node.ELEMENT_NODE is declared const in the IDL. Though that requires Special Knowledge.

    JavaScript, compiler, constant-folding… How we laughed.

  6. rptb1 Says:

    It’s more fun if you say switch(false)! Kinda reminds me of the “while … dont” construct.

  7. Graham Says:

    Usinf Switch (true) etc. is useful if you need to compare a range of values; e.g.:
    switch (true){
    case keynum==0:
    do something
    case keynum==13:
    do something else
    case keynum>76:
    do something more
    }

  8. Eric Garside Says:

    It’s also useful for replacing a multiline if/then for the sake of cleanliness/readability. Take the function foo() where we pass in a jQuery element and need to check for a certain class:

    function foo(element){
    if (element.hasClass(‘something’)) {
    fire();
    } else if (element.hasClass(‘else’)) {
    fire2();
    } else if (element.hasClass(‘another’)) {
    fire3();
    }
    }

    We can rewrite this to:

    function foo(element){
    switch(true){
    case element.hasClass(‘something’): fire(); break;
    case element.hasClass(‘else’): fire2(); break
    case element.hasClass(‘another’): fire3(); break
    }
    }

  9. bob Says:

    may be nice to replace the switch with an object like

    var perClassAction = {
    ‘something’ : fire,
    ‘somethingelse’ : fire2,
    // a lot more to make this a useful pattern
    ‘finally’ : theLastFunction
    }
    classnames.forEach( function (className) {
    if perClassAction(className) {
    perClassAction[className]()
    }
    }

    setting up a classname based form validation could make sense like this

    i have a dislike for switch because it requires you to break, they should’ve made a fallthrough statement instead.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: