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.
2007-09-03 at 09:39:08
Maybe people use the numeric values because it lets the compiler use the fact that they are constants?
2007-09-03 at 09:54:46
Could be. The Javascript community seems to attract all sorts.
2007-09-03 at 10:30:38
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.
2007-09-03 at 15:15:30
Yes, like C, JavaScript’s cases followthrough / require
break. Though unlike C, thecaseclauses are not independent; they must appear as the direct children of theswitch‘s caseblock and not, for example, embedded inside an interiorwhilestatement. 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.
2007-09-03 at 15:20:07
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
constin the IDL. Though that requires Special Knowledge.JavaScript, compiler, constant-folding… How we laughed.
2007-09-04 at 07:51:41
It’s more fun if you say switch(false)! Kinda reminds me of the “while … dont” construct.
2008-08-13 at 15:15:10
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
}
2008-11-18 at 17:00:45
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
}
}
2010-02-27 at 13:37:28
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.