Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript switch case using enum

Tags:

I have an "enum" declared like so:

var PlaceType = {
        PASSABLE_TERRAIN: 1,
        IMPASSABLE_TERRAIN: 0,
        SOMEWHAT_PASSABLE_TERRAIN: 2,
        PATH: 3
    };

and a function declared like this:

setPlaceType(placeType) {
        this.clear = false;
        this.placeType = placeType;

        alert("before switch "+(PlaceType.SOMEWHAT_PASSABLE_TERRAIN==this.placeType));
        switch(this.placeType) {
        case PlaceType.PASSABLE_TERRAIN: {
            alert("Case PASSABLE");
            break;
        }
        case PlaceType.IMPASSABLE_TERRAIN: {
            alert("Case IMPASSABLE");
            break;
        }
        case PlaceType.SOMEWHAT_PASSABLE_TERRAIN: {
            alert("Case SOMEWHAT_PASSABLE");
            break;
        }
        case PlaceType.PATH: {
            alert("Case PATH");
            break;
        }
        default: {
            alert("case default");
        }
        }
    }

if I call it like this:

setPlaceType(1);

I get the following alerts: "before switch true", "case default"

if I call it like this:

setPlaceType(2);

I get the following alerts: "before switch false", "case default"

In other words, the function is called with the proper argument, which, when doing (what it seems to me to be) the same comparison as the switch but via "==" I get correct behavior, but the switch never matches the values to the appropriate case. Does anybody know why?

like image 866
Shivan Dragon Avatar asked Oct 08 '12 14:10

Shivan Dragon


1 Answers

The comparison operator will cast both operands to strings if either operator is a string. If you pass in a string, you are comparing string == number which will cast the number to a string and, in the case of passing the string '2', it will be true.

switch case comparison uses the identity operator === and will fail if the operands are not the same type.

long story short, make sure you are always passing a number if your cases are comparing against numbers, you can double check like this:

setPlaceType(placeType) {
    if (typeof placeType !== 'number') {
        throw new Error('You must pass a number to setPlaceType!');
    }
    ...
}

also, you should be calling your function like this:

setPlaceType(PlaceType.PASSABLE_TERRAIN);

otherwise there's not really any point to using the "enumeration" (i use that term loosely) object.

like image 81
jbabey Avatar answered Oct 05 '22 18:10

jbabey