【问题标题】:trouble with SWITCH javascript always executing default caseSWITCH javascript总是执行默认情况的问题
【发布时间】:2012-09-05 05:49:39
【问题描述】:

我遇到了这个麻烦,我一直在处理,但我就是无法让它工作

我有这个功能

function getDirections(dir)
{
var img;
switch(dir)
    {
    case 0:
    img+='N.png';
    break;  
    case 1:
    img+='NE.png';
    break;
    case 2:
    img+='E.png';
    break;
    case 3:
    img+='SE.png';
    break;
    case 4:
    img+='S.png';
    break;
    case 5:
    img+='SO.png';
    break;
    case 6: 
    img+='O.png';
    break;
    case 7:
    img+='NO.png';
    break;
    default:
    alert('enetered default but direction='+dir);
    }
return img;
}

很简单吧?现在我将此间隔设置为 5000 毫秒来调用 getDirections(variable),该函数在第一次调用时运行良好,但之后,它总是进入默认子句,它还会提醒“输入默认值但方向 = dirvalue”,我的意思是,即使 dir 是一个介于 0-7 之间的值,它也将始终输入默认值:但它会提醒该值,因此应该输入其中一种情况。

我用 else if 做了同样的事情,它工作了,所以我不知道 SWITCH 有什么问题

if(dir==0){img+='N.png';}
else if(dir==1){img+='NE.png';}
else if(dir==2){img+='E.png';}
else if(dir==3){img+='SE.png';}
else if(dir==4){img+='S.png';}
else if(dir==5){img+='SO.png';}
else if(dir==6){img+='O.png';}
else if(dir==7){img+='NO.png';}

【问题讨论】:

  • 如果你在函数顶部记录dir,你会得到预期的结果吗?
  • 该代码在 Firefox 中对我来说运行良好,是否涉及其他代码?你使用的是什么浏览器?您可能还想添加var img="";,因为它会在追加时尝试将两个操作数都转换为字符串,并且由于您尚未初始化 img 它只是变为“未定义”。 :)
  • switch...case uses strict comparison;您正在将字符串与整数进行比较。

标签: javascript switch-statement


【解决方案1】:

这很奇怪...尝试确保 dir 是一个 int,在切换之前执行此操作:

dir = parseInt(dir);

如果警报正确显示值,它应该进入开关,但它仍然可以“看起来”正确,但数据类型不同。手动进行转换以确保它是 int

【讨论】:

  • parseInt 是不需要的。 + 一元运算符是要走的路:switch ( +dir ) { ...
  • 你是对的,似乎获取的数据是字符串,所以只需添加 parseInt 以及将 case 1: 更改为 case '1':
  • 您可以通过多种不同的方式转换为 int,这只是代码风格 :) 我更喜欢在转换时明确而不是使用非 JavaScript 程序员(或初学者)可以使用的 +dir 之类的东西不明白。
【解决方案2】:

我知道我参加聚会有点晚了,但我认为对于那些不理解“ifs”为什么起作用而开关不起作用的人来说,这可能很重要。可能没有人会阅读此答案,但我在搜索其他内容时发现了它,所以也许有人会觉得这很有帮助:

你的开关是这样的:

function getDirections(dir) {
    var img;
    switch(dir) {
        case 0:
            img+='N.png';
            break;  
        case 1:
            img+='NE.png';
            break;
        case 2:
            img+='E.png';
            break;
        case 3:
            img+='SE.png';
            break;
        case 4:
            img+='S.png';
            break;
        case 5:
            img+='SO.png';
            break;
        case 6: 
            img+='O.png';
            break;
        case 7:
            img+='NO.png';
            break;
        default:
            alert('enetered default but direction='+dir);
    }
    return img;
}

这与一系列双等号 (==) 不同,而是一系列三等号 (===)。相当于:

if (dir === 0) {
    img+='N.png';
} else if (dir === 1) {
    img+='NE.png';
} else if (dir === 2) {
    img+='E.png';
} else if (dir === 3) {
    img+='SE.png';
} else if (dir === 4) {
    img+='S.png';
} else if (dir === 5) {
    img+='SO.png';
} else if (dir === 6) {
    img+='O.png';
} else if (dir === 7) {
    img+='NO.png';
} else {
    alert('enetered default but direction='+dir);
}

在“==”的世界里,整数2和字符串“2”是一样的,但在“===”的世界里却不是。

【讨论】:

    【解决方案3】:

    我猜出于某种原因 dir 作为字符串传入。尝试将 case 1: 更改为 case '1':

    【讨论】:

      【解决方案4】:

      使用数组而不是 if/else 块链或巨大的 switch 语句将更快、更灵活且不易出错。此外,您不必担心dir 是数字还是字符串。而不是:

      if(dir==0){img+='N.png';}
      else if(dir==1){img+='NE.png';}
      else if(dir==2){img+='E.png';}
      else if(dir==3){img+='SE.png';}
      else if(dir==4){img+='S.png';}
      else if(dir==5){img+='SO.png';}
      else if(dir==6){img+='O.png';}
      else if(dir==7){img+='NO.png';}
      

      您可以将文件名存储在数组中:

      var images = [
          'N.png', 'NE.png', 'E.png', 'SE.png', 'S.png', 'SO.png', 'O.png', 'NO.png'
      ];
      

      或者可以说更具可读性:

      var images = "N.png NE.png E.png SE.png S.png SO.png O.png NO.png".split(' ');
      

      然后只使用:

      img = images[dir];
      

      使用数组的 getDirections 的完整实现是:

      var images = "N.png NE.png E.png SE.png S.png SO.png O.png NO.png".split(' ');
      function getDirections(dir) {
          var img = images[dir];
          if (!img) {
              alert("something");
          }
          return img;
      }
      

      它对你有用吗?

      如果 images 仅用于该函数,那么您可能希望将其存储为函数的属性以避免您的命名空间污染,如下所示:

      function getDirections(dir) {
          var img = getDirections.images[dir];
          if (!img) {
              alert("something");
          }
          return img;
      }
      getDirections.images =
          "N.png NE.png E.png SE.png S.png SO.png O.png NO.png".split(' ');
      

      或使用闭包。

      【讨论】:

      • 确保先将 dir 转换为 int。这是一个更清洁的解决方案,但仍然不能解释用户遇到的问题。 :)
      • 如果问题是dir 是一个字符串,那么它将以这种方式工作。看到这个小提琴:jsfiddle.net/cAg58
      • 1.它必须是+=,而不是=。 2.可以去掉.png后缀去掉冗余。然后:img += arr[dir] + '.png';
      • 它不必是 += 因为 img 总是以空字符串开头。
      【解决方案5】:

      很难解释为什么,但default: 的情况与所有其他情况一样,在它之后也需要一个break; 语句。

      【讨论】:

      • ...不一定,因为它是最后一个。不过,为了便于阅读,将其放入其中仍然是一个好主意。
      【解决方案6】:

      我刚刚在 FireFox/FireBug 中运行代码并以这种方式调用函数

      getDirections(0);
      getDirections('1');
      getDirections("2");
      

      第一个正确,接下来的两个输入default。 它们是字符串而不是整数,这是案例正在寻找的。 我加了

      case "2":
      img+='NO2.png';
      break;
      

      然后只有中间的一个输入了default。显然,您调用该函数的方式存在问题。它可能会传递一个字符串。 我还使用了您的 if-else 块(添加了一个 else{alert(dir);} 并为每个调用返回了正确的值。

      Javascript 可以在字符串和整数(以及其他)之间进行动态转换(我认为有一个更好的词)。当您使用== 进行比较时会发生这种情况。如果您将ifs 中的比较更改为===,您将获得与switch 块相同的行为。

      【讨论】:

        【解决方案7】:

        我将您的代码粘贴到一个 HTML 文件中并使用以下按钮运行它:

        <button onclick="alert(getDirections(2))">Switch / Int</button>
        <button onclick="alert(getDirections('2'))">Switch / String</button>
        <button onclick="alert(getDirections2(2))">If-Else / Int</button>
        <button onclick="alert(getDirections2('2'))">If-Else / String</button>
        

        当使用纯 2 调用 switch-version 时,它会按预期工作。使用'2' 调用它会使其进入default 行。 if-else 版本在这两种情况下都按预期工作。所以问题可能是switch 没有进行隐式转换,而== 进行了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-05-19
          • 2021-10-01
          • 2020-07-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-16
          相关资源
          最近更新 更多