Rupert
Rupert

Reputation: 539

it's weird that the switch condition in javascript

I find that these two below are equivalent, but is quit weird that, single = is not a relation operator but an assignment operator, why it works in the second one?

First:

switch (true) 
  {
    case color == 'green':case color == 'red':case color == 'blue':case color == 'pink':
      alert('colorful')
      break;
    case color == 'black':case color == 'white':
      alert('classical')
      break;
    default:
      alert('dull')
      break;              
  }

Second:

switch (color) 
  {
    case color = 'green':case color = 'red':case color = 'blue':case color = 'pink':
      alert('colorful')
      break;
    case color = 'black':case color = 'white':
      alert('classical')
      break;
    default:
      alert('dull')
      break;              
  }

Upvotes: 5

Views: 256

Answers (2)

marsze
marsze

Reputation: 17035

I don't know exactly how switch's work (inside the CPU), but I assume the value of color is temporarily stored when the switch statement is entered. Then, the result of the assignments, which equal the value that is assigned, are compared with that stored switch-value, not the variable itself. It's because, I think, you could also do this:

var color = 'whit'
switch(color + 'e')
// value "white" stored for comparison...
{
  case color = 'green':
  case color = 'red':
  case color = 'blue':
  case color = 'pink':
    alert('colorful')
    break;
  case color = 'black':
  // (color = 'white') == 'white'
  // 'white' is compared to the stored value
  case color = 'white':
    alert('classical')
    break;
  default:
    alert('dull')
    break;              
}

UPDATE: In the following example, value is only retrieved once (at the beginning of the switch statement) but set several times (in each case statement). Ergo: only the value of the variable (not the variable itself) is used for comparison.

function Field(val){
    this.__defineGetter__("value", function(){
        var val = parseInt(Math.random() * 10);
        console.log('get: ' + val);
        return val;
    });
    this.__defineSetter__("value", function(val){
        console.log('set: ' + val);
    });
}

var field = new Field();
switch (field.value) {
    case field.value = 0:
        break
    case field.value = 1:
        break
    case field.value = 2:
        break
    case field.value = 3:
        break
    case field.value = 4:
        break
    case field.value = 5:
        break
    case field.value = 6:
        break
    case field.value = 7:
        break
    case field.value = 8:
        break
    case field.value = 9:
        break
    default:
        break
}

// output (e.g.)
// get: 5
// set: 1
// set: 2
// set: 3
// set: 4
// set: 5

Upvotes: 0

Orel Eraki
Orel Eraki

Reputation: 12196

At the first switch statement your checking for boolean value. So the valid results will be either true or false.

For the second switch statement we're searching for a color. The result of assignment is the assignment value it self.

color = 'green' will return green and will be exactly like writing case 'green': except that it will also change the value of color. BUT and it's a big but, you are changing the value of color while checking what the color and that may cause big side effects.

You better use the correct formal style for case 'green': and not other variations. Especially not assignment variations.

Upvotes: 8

Related Questions