How do you have a NaN case in a switch statement?

后端 未结 4 1452
滥情空心
滥情空心 2021-02-04 12:20

Since NaN === NaN evaluates to false, is it possible to add a NaN case to a switch statement?

For example, let\'s say

相关标签:
4条回答
  • 2021-02-04 12:21

    You could do this (jsFiddle):

    var x = "test";
    switch (isNaN(x) || x)
    {
        case true:
          alert("IsNaN!") 
          break; 
        case 1: 
          alert("1"); 
          break; 
        case 2: 
          alert("2"); 
          break; 
        case 4: 
          alert("4"); 
          break; 
        default: 
          alert("default"); 
          break; 
    }
    

    Or if you also want to validate string containing a number (jsFiddle):

    var x = "1";
    switch (isNaN(x) || parseInt(x))
    {
        case true:
          alert("IsNaN!") 
          break; 
        case 1: 
          alert("1"); 
          break; 
        case 2: 
          alert("2"); 
          break; 
        case 4: 
          alert("4"); 
          break; 
        default: 
          alert("default"); 
          break; 
    }
    
    0 讨论(0)
  • 2021-02-04 12:23

    use toString():

    switch (x.toString()) {
        case '1':
        case '2':
        case '4':
            console.log('1/2/4');
            break;
        case 'NaN':
            console.log('NaN');
            break;
        default:
            console.log('default');
    }
    
    0 讨论(0)
  • 2021-02-04 12:31

    @helmus's answer is correct and is a good solution.

    However, you can maintain the NaN case if you use strings:

    switch(x+''){
        case "1":
        case "2":
        case "4":
            doSomething();
            break;
        case "NaN":
            doSomethingElse();
            break;
        default:
            doADifferentThing();
            break;
    }
    
    0 讨论(0)
  • I originally wrote i saw only one solution, however during my sleep i came up with a superb solution.

    Always keep in mind that a switch does not do implicit type conversion to compare the cases so if you provide a string to the switch statement it will not match to integers in the cases, and vice versa. If you want to compare to strings and integers you will have to cast your integer to a string first and then compare to strings only.

    The superb solution:

    As pointed out by WouterH, my initial solution will resolve to default when using a string that contains a number, this is expected behavior for switch statements. But it might be useful to parse the argument in order to overcome this. For that you can use following code:

    var x = "1";
    switch (isNaN(x) || parseInt(x))
    {
        case true:
          alert("IsNaN!") 
          break; 
        case 1: 
          alert("1"); 
          break; 
        case 2: 
          alert("2"); 
          break; 
        case 4: 
          alert("4"); 
          break; 
        default: 
          alert("default"); 
          break; 
    }
    

    My initial superb method :

    var x = "clearly not a number";
    switch(x){
        case !isNaN(x) || x:
          alert("IsNaN!")
          break;
        case 1:
          alert("1");
          break;
        case 2:
          alert("2");
          break;
        case 4:
          alert("4");
          break;
        default:
          alert("default");
          break;
        }
    

    isNaN will return true if x where to be a string but it doesn't really matter because true won't evaluate as true to a string because of the above mentioned behavior of the switch statement.

    My original solution:

    I don't even know what i was thinking, this looks horrible and the indentation is just plain awkward, but thanks for the upvotes !

    var x = "clearly not a number";
    switch(x){
        case 1:
          alert("1");
          break;
        case 2:
          alert("2");
          break;
        case 4:
          alert("4");
          break;
        case default:
           if (isNaN(x)){
              alert("isNaN");
              break;
           }
           alert("default");
           break;
    }
    

    Brad's solution:

    thx to Brad for this one. I don't really like this because it feels a bit like a hack, that is to say, this isn't how you would expect usage of a case statement, but it does give you the most flexibility, so i'm certain there is a use case for it.

    var x = "clearly not a number";
    switch(true)
    {
       case x==1:
          alert("1");
          break;
       case x==2:
          alert("2");
          break;
       case IsNaN(x):
          alert("IsNaN");
          break;
       case default:
          alert("default");
          break;
    }
    
    0 讨论(0)
提交回复
热议问题