Reputation: 381
I just encountered a boolean switch statement in someone else's JavaScript code. It looked a little bit like this:
switch (a || b) {
case true:
// do some stuff
break;
default:
// do other stuff
break;
}
I haven't been programming for very long, but I certainly have never seen anything like this before. It seems kind of stupid, but I would like to give the programmer the benefit of the doubt. Is there any functional difference between the above code and the following:
if (a || b) {
// do some stuff
}
else {
// do other stuff
}
And if there is, what is it?
Upvotes: 8
Views: 7090
Reputation: 75862
To be clear this case looks abusive, but since Javascript isn't strongly typed in principle it can be valuable where you can't control the input:
switch (foo)
{
case true:
// whatever
break;
case false:
// whatever
break;
default:
// FOO IS NOT A BOOLEAN, DO SOMETHING ELSE!
break;
}
As well as Andrew's mixed case. This is a bit safer than a simple if/else, and more concise than some kind of boolean checking and then an if/else.
Upvotes: 2
Reputation: 126072
Updated after Andy's comment and answer
There's no difference (in your example), but in your example, the if
block is more readable and makes more sense in that case (in my opinion).
switch
ing on a statement that evaluates to a boolean
seems wrong just because there will always only be two cases (true
and false
), and for this reason I'd recommend the if
block instead.
switch
makes more sense when you're evaluating a variable that could have many values:
switch(fruitType) {
case 'Apple':
// Apple Code
break;
case 'Orange':
// Orange Code
break;
// etc...
default: // other fruit
break;
}
Hope that helps!
Upvotes: 1
Reputation: 344675
Yes, there's a difference. Taking your example into account,
var a = 0,
b = 1;
Now let's look at the switch
statement:
switch (a || b) {
When this switch statement is run, the expression a || b
is evaluated. ||
is a short-circuit operator, it will return the left operand's value if it's "truthy", else it will return the right operand's value. In this case, a = 0
, so b
will be returned (1
). Now look at the case
statement:
case true:
When evaluating case
statements, no type coercion is performed on either value and strict equality is assumed. In our example, this is the same as writing 1 === true
, so the code following the case
statement is never run. So let's take a look at the if
statement:
if (a || b) {
For an if
statement, the conditional expression a || b
is evaluated and then the result is converted to a boolean. Internally, this looks like ToBoolean(a || b)
. Since a || b
evaluates to 1
and coercion of 1
to a boolean is true
, the condition passes and the block executes.
A better equivalent would be:
if ((a || b) === true) {
// do some stuff
}
else {
// do other stuff
}
As already pointed out, in situations where there are many cases and types could vary, a switch
statement could be useful. Such a situation would be rare, however.
Upvotes: 8
Reputation: 2941
Your example doesn't show it, but I think that this may make for more concise code if you want to use a fallthrough (ie, no break) in the first case
, depending on the situation.
It also may be a decent construct if you are implementing something in a way that anticipates potential changes and want to have minimal rework (eg, want to keep the actions the same while just redoing the selection logic).
Upvotes: 0
Reputation: 108500
In your example, there is no difference. But depending on how a
and b
is defined, you could add more switch statements later on, f.ex:
var a = false, b = null;
switch (a || b) {
case true:
// do some stuff
break;
case null:
// do some stuff
break;
default:
// do other stuff
break;
}
Other than that, it's mostly a matter of coding preference.
Upvotes: 0