【问题标题】:JavaScript switch case using enum使用枚举的 JavaScript 切换案例
【发布时间】:2012-09-28 19:33:39
【问题描述】:

我有一个这样声明的“枚举”:

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

还有一个这样声明的函数:

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");
        }
        }
    }

如果我这样称呼它:

setPlaceType(1);

我收到以下警报:“在 switch true 之前”、“case default”

如果我这样称呼它:

setPlaceType(2);

我收到以下警报:“在 switch false 之前”、“case default”

换句话说,该函数是使用正确的参数调用的,当做(在我看来是)与开关相同的比较但通过“==”时,我得到了正确的行为,但开关永远不会将值与适当的情况相匹配。有人知道为什么吗?

【问题讨论】:

  • 它对我有用:jsfiddle.net/Y2KEn 你确定你正在传递一个 int 吗?
  • 您是否通过调试器运行此程序以查看 Javascript 对 Case 块中比较值(或入站值)的运行时类型的看法?只是想知道它是否是一个微妙的强制问题? (在黑暗中拍摄)
  • 您是否有机会从 HTML 页面调用它并传入输入文本框的 value 属性?那肯定会发送一个字符串...

标签: javascript enums switch-statement case


【解决方案1】:

如果任一运算符是字符串,则比较运算符会将两个操作数转换为字符串。如果你传入一个字符串,你正在比较string == number,这会将数字转换为一个字符串,并且在传递字符串'2'的情况下,它会是真的。

switch case 比较使用标识运算符===,如果操作数的类型不同,则会失败。

长话短说,如果您的案例与数字进行比较,请确保您始终传递一个数字,您可以像这样仔细检查:

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

另外,你应该这样调用你的函数:

setPlaceType(PlaceType.PASSABLE_TERRAIN);

否则,使用“枚举”(我松散地使用该术语)对象实际上没有任何意义。

【讨论】:

  • 我可能是错的,但我认为在 javascript 中,类型强制总是尝试将两种类型转换为数字,除非它们是相同的类型;不在字符串中。请阅读这篇好文章:javascriptweblog.wordpress.com/2011/02/07/…
【解决方案2】:

参考这个 => Switch-Case for strings in Javascript not working as expected

Switch 执行===,而if 执行==

希望对您有所帮助!祝你有美好的一天

【讨论】:

    【解决方案3】:

    当您使用 == 进行比较时,js 正在使用 type-coercion 将 2 个操作数转换为中间类型,在这种情况下为字符串,从而成功比较它们。

    所以要让你的 switch 语句产生效果,你需要这样转换

    this.placeType = parseint(placeType);
    

    您还必须在这里学到的是,在 javascript 中使用 == 运算符比较两个值并不是一个理想的做法,而是使用 === 运算符来检查类型是否相同。所以在你的情况下,

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

    如果您在比较intstring 时使用===,则会失败

    这里的工作演示:http://jsfiddle.net/pratik136/ATx8c/

    【讨论】:

      【解决方案4】:

      匹配大小写使用the === identity operator, not the == equality operator 确定。表达式必须匹配,无需任何类型转换。如果您传入的是字符串而不是整数,它将失败。

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

      使用上述行运行代码的示例:jsFiddle

      所以如果你说它失败了,你可能是在比较一个字符串和一个数字。使用 parseInt。

      this.placeType = parseint(placeType,10);
      

      【讨论】:

      • 谢谢,就是这样。然而,“==”检查通过但开关检查没有通过的事实确实违反直觉。我现在明白开关实际上会进行“===”检查,但仍然。
      • 嗯,是的,因为它还解释了“==”和“===”,我认为如果/当他/她被这个问题绊倒了。
      【解决方案5】:

      另一种使用枚举作为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]);
           }
      

      【讨论】:

      • 如何使用上述场景来处理未定义或等于或大于4的值
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多