admin管理员组

文章数量:1195770

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?

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?

Share Improve this question edited Oct 8, 2012 at 16:05 Bo Persson 92.2k31 gold badges153 silver badges208 bronze badges asked Oct 8, 2012 at 14:18 Shivan DragonShivan Dragon 15.2k10 gold badges67 silver badges104 bronze badges 3
  • 1 It works for me: jsfiddle.net/Y2KEn are you certain you are passing an int? – scrappedcola Commented Oct 8, 2012 at 14:25
  • 1 Have you run this through a debugger to see what Javascript thinks about the runtime type of the comparison values in the Case blocks (or the inbound value, for that matter)? Just wondering if its a subtle coercion problem? (Shot in the dark) – David W Commented Oct 8, 2012 at 14:25
  • 1 Any chance you're calling this from an HTML page and passing in the value property of a input text box? That would surely send a string... – David W Commented Oct 8, 2012 at 14:28
Add a comment  | 

5 Answers 5

Reset to default 9

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.

Another way to use enum for switch case:

   const PlaceType = Object.freeze({
            PASSABLE_TERRAIN: 1,
            IMPASSABLE_TERRAIN: 0,
            SOMEWHAT_PASSABLE_TERRAIN: 2,
            PATH: 3
        });

   function setPlaceType(placeType){
      return({
              0:"Case IMPASSABLE_TERRAIN",
              1:"Case PASSABLE_TERRAIN",
              2:"Case SOMEWHAT_PASSABLE_TERRAIN",
              3:"PATH"      
              }[placeType]);
     }

Refering to this => Switch-Case for strings in Javascript not working as expected

Switch do a ===, while if do a ==.

Hope this help! have a nice day

When you are doing the comparison using == js is using type-coercion to cast the 2 operands to an intermediate type, string in this case, and thus compare them successfully.

So to get the effect to work with your switch statement, you will need to cast as such

this.placeType = parseint(placeType);

What you also got to learn here is that it is not really an ideal practice to compare 2 values in javascript using the == operator, instead use the === operator which also checks for the types to be the same. So in your case,

alert("before switch "+(PlaceType.SOMEWHAT_PASSABLE_TERRAIN==this.placeType));

would have failed if you would have used === as you are comparing an int and string

Working demo here: http://jsfiddle.net/pratik136/ATx8c/

The matching case is determined using the === identity operator, not the == equality operator. The expressions must match without any type conversion. It would fail if you are passing in a string and not an integer.

setPlaceType(1);  //"Case PASSABLE"
setPlaceType("1");  //"case default"

Example running your code with the above lines: jsFiddle

So if you are saying it is failing, you are probably comparing a string to a number. Use parseInt.

this.placeType = parseint(placeType,10);

本文标签: JavaScript switch case using enumStack Overflow