Why does the logical OR operator in switch cases behave strangely?

Viewed 230

The testMyNumber function seems to think numbers in the second position do not match.

Why do 4 and 10 return the default case?

function testMyNumber(number) {
  switch (number) {
    case 6:
      return number+" is 6";
      break;
    case (3 || 4) :
      return number+" is 3 or 4";
      break;

    case 9 || 10 :
      return number+" is 9 or 10";
      break;

    default:
      return number+" is not in 3,4,6,9,10";
      break;
  }
};
console.log(testMyNumber(6));
console.log(testMyNumber(3));
console.log(testMyNumber(4));
console.log(testMyNumber(9));
console.log(testMyNumber(10));

Is there a way to make this work?

7 Answers

Because it wasn't intended to be used this way.

|| returns its first operand if it's truthy, else its second operand.

3 || 4 returns 3 because 3 is truthy, therefore case will check only 3:

console.log(3 || 4); //3, because it is truthy
console.log(0 || 1); //1, because 0 is falsy

To make your code work, use separate cases, that fall through:

function testMyNumber(number) {
  switch (number) {
    case 6:
      return number+" is 6";
    case 3:
    case 4:
      return number+" is 3 or 4";

    case 9:
    case 10:
      return number+" is 9 or 10";
    default:
      return number+" is not in 3,4,6,9,10";
  }
};
console.log(testMyNumber(6));
console.log(testMyNumber(3));
console.log(testMyNumber(4));
console.log(testMyNumber(9));
console.log(testMyNumber(10));

Why 4 returns default case?

Because (3 || 4) is equal to 3, so case (3 || 4): is the same as writing case 3:.

You are using incorrect syntax. Write it like this:

case 3:
case 4:
    return number + " is 3 or 4";

Because (3 || 4) is 3 and its not 4, so it jumps to default.

console.log((3 || 4));

var test = 4;

switch(test){
   case 3:
   case 4:
      console.log("3 and 4");
      break;
   default:
      console.log("default");
}

Write that cases underneath

The reason is in two parts.

First of all, switch statements in JS cannot handle multiple values in a single case.

So what happens when you try to do so? Well see below.

console.log(3 || 4);

Now why does 3 || 4 evaluate to 3. To understand this, think about the OR operator with booleans.

bool_a || bool_b. If the bool_a is true, then the expression evaluates to true, think of this as evaluating to bool_a. If the value is false it will essentially return bool_b.

In Javascript this is exactly how things work. Just replace true and false with truthy and falsy.

console.log(0 || 2);
console.log([]|| 2);
console.log(''|| 2);
console.log(false|| 2);

console.log("aaa" || 2);
console.log(true || 2);

To do this the way you want

case 3:
case 4:
    return number + " is 3 or 4"

If you do 3 || 4 the answer is 3.

The correct way to do this is like this

function testMyNumber(number) {
  switch (number) {
    case 6:
      return number+" is 6";
      break;
    case 3:
    case 4:
      return number+" is 3 or 4";
      break;

    case 9:
    case 10 :
      return number+" is 9 or 10";
      break;

    default:
      return number+" is not in 3,4,6,9,10";
      break;
  }
};

Because of the way the syntax works in JavaScript, your case 4: is never defined.

When you say case (3 || 4):, you're telling JavaScript the name for just one case, the case of whatever your expression evaluates to. In this example, (3 || 4) evaluates to 3, so you're telling JavaScript case 3:.

The first code sample on MDN shows what you are trying to do

case (3 || 4) always evaluates to 3 because 3 is truthy.

You could instead use multiple cases:

function testMyNumber(number) {
  switch (number) {
    case 6:
      return number+" is 6";
      break;
    case 3:
    case 4:
      return number+" is 3 or 4";
      break;
    case 9:
    case 10:
      return number+" is 9 or 10";
      break;
    default:
      return number+" is not in 3,4,6,9,10";
      break;
  }
};

console.log(testMyNumber(6));
console.log(testMyNumber(3));
console.log(testMyNumber(4));
console.log(testMyNumber(9));
console.log(testMyNumber(10));

See the MDN switch docs.

Related