Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Samer Sadek
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Samer Sadek@samer_sadek )

Switch Cases Do Not Have To Be Static In JavaScript

By Ben Nadel on

In ColdFusion, Switch Cases have to be static. Meaning, the value of a Case statement has to be hard-coded within the source code. Having been a ColdFusion developer for a long time, I just assumed that this is how it worked in other languages as well - I figured it was some sort of compile-time / optimization requirement. But, this morning, I just realized that this is not the case in JavaScript (no pun intended). In JavaScript, switch cases can be dynamic values.

To test this for myself (and I even went back and tested this on IE7 to make sure I wasn't crazy), I created a simple page that would log the value of variable based on both static and dynamic case values:

  • <!doctype html>
  • <html>
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • Switch Cases Do Not Have To Be Static In JavaScript
  • </title>
  • </head>
  • <body>
  •  
  • <h1>
  • Switch Cases Do Not Have To Be Static In JavaScript
  • </h1>
  •  
  • <script type="text/javascript">
  •  
  • var userInput = "foo";
  •  
  •  
  • // --------------------------------------------------------------------------- //
  • // --------------------------------------------------------------------------- //
  •  
  •  
  • // In this version, our CASE values are going to be static, hard-coded values.
  • switch ( userInput ) {
  •  
  • case "foo":
  • console.log( "User entered 'Foo'." );
  • break;
  •  
  • case "bar":
  • console.log( "User entered 'Bar'." );
  • break;
  •  
  • case "baz":
  • console.log( "User entered 'Baz'." );
  • break;
  •  
  • }
  •  
  •  
  • // --------------------------------------------------------------------------- //
  • // --------------------------------------------------------------------------- //
  •  
  •  
  • // In this version, our CASE values are going to be dynamic variables that will
  • // be evaluated, on the fly, as the runtime moves down the list.
  • var INPUT_FOO = "foo";
  • var INPUT_BAR = "bar";
  • var INPUT_BAZ = "baz";
  •  
  • switch ( userInput ) {
  •  
  • case INPUT_FOO:
  • console.log( "User entered 'Foo'." );
  • break;
  •  
  • case INPUT_BAR:
  • console.log( "User entered 'Bar'." );
  • break;
  •  
  • case INPUT_BAZ:
  • console.log( "User entered 'Baz'." );
  • break;
  •  
  • }
  •  
  •  
  • // SIDE NOTE: In ColdFusion, this approach to Switch / Case statements would
  • // error with the following: "This expression must have a constant value."
  •  
  • </script>
  •  
  • </body>
  • </html>

As you can see, in the first switch block, the case values are hard-coded. And, in the second switch block, the values are based on dynamic variables. When we run this code, we get the following console output:

User entered 'Foo'.
User entered 'Foo'.

Holy cow! This kind of blew my mind. It's scary to think that I misunderstood such a fundamental feature of the JavaScript language; and, for so many years! I guess it's never too later to learn.




Reader Comments

When you use switch (true), you can use different if-statements as case:

<pre>
function test() {
console.log('test');
return true;
}
switch (true) {
case test():
console.log('foo');
break;
default:
console.log('default');
break;
}
</pre>

This logs 'test' and 'foo' to the console.

Reply to this Comment

@Robert,

That's pretty crazy that you can use a Function *call* as the "case" value. JavaScript - you so dynamic :D

Reply to this Comment

@Mike,

I'm just always shocked that I keep learning these little things. For a language has a relatively small syntax, it seems to always surprise me :D

Reply to this Comment

Ben,

I'm not working in ColdFusion anymore, so I can't check, but I wonder if CFScript (as opposed to CFML) can handle dynamic cases. I wouldn't be surprised either way.

Reply to this Comment

@Adam,

Ah, good to know. I do think that multiple case statements can *look* much nicer than if/else-if statements, especially when they are switching on a single value. In the past, I've had to fallback to if/else-if because of the limitation. Good to know it's way more prevalent than I realized.

Reply to this Comment

Pardon me but did you mean final or constant variables? I don't think static is correct in this context. The static keyword means that something (a field, method or nested class) is related to the type rather than any particular instance of the type.

Reply to this Comment

@Edward: a better description would perhaps be a *constant value*. And the only way to express a constant value in CFML is with a literal. It also, as far as I can tell, must be a simple literal.

Reply to this Comment

@Adam... Ya... Java has the same constraints on lambda expressions ... the variables have to be 'final or effectively final' ~ immutable.

Reply to this Comment

@Adam, @Edward,

You guys talk like you think I have any idea what I'm talking about most of the time :P I know very little about the terminology of actual computer science. What I meant was that the CASE value had to be a "literal" maybe? I am not sure what the correct term would be.

Reply to this Comment

@Ben... :) NP ... I hope I didn't come across as a critique man... I was just confused by the 'static' reference... I believe you were trying to express was an immutable variable, which, has a final, constant value ~ "This expression must have a constant value." ~ sorry for the long wind ;)

Reply to this Comment

@Edward,

No offense taken at all :) I wish I knew more about correct terminology.

I'll take a look at Eric's stuff. His articles are always quality.

Reply to this Comment

@Ben... I learned a lot of terminology when studying Java... In most statically typed langauges you're required to understand modifiers... dynamic langs dont really necessitate that.

Reply to this Comment

@Edward,

All I know is that I used to try to sub-class certain ColdFusion classes, but they are all flagged as "Final" so you can't mess with them :)

Reply to this Comment

Good to know, Ben. BTW, I'm still coding in CF and, like the Godfather, just when I thought I was out, they -- and lots of posts that refer back to BenNadel.com -- keep pulling me back to your blog!

Reply to this Comment

You scared me there for a bit. I thought i missed that you can dynamically insert case statements to a switch.

Reply to this Comment

@Emir,

Ha ha, that would be interesting. Though, I have seen approaches like that were people use a hash instead of a set of case statements. Like, they will use something like:

commands.foo = function(){ ... };
commands.bar = function(){ ... };
commands.baz = function(){ ... };

... And then, instead of a switch/case paradigm they will do something like:

commands[ switchValue ].call( ... )

With that kind of approach, you could dynamically add "case" statements by adding new keys to the hash.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.