SWITCH JavaScript出现问题,总是执行默认情况

3
“我有这个问题,一直在处理,但就是无法让它正常工作。”
“我有这个函数。”
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)函数,第一次调用该函数时它运行得很好,但之后,它总是进入默认情况,并且还会弹出“已输入默认,但direction=dirvalue”的警报,我的意思是,即使dir是0-7之间的值,它也总是进入default:,但它会发出值警报,因此它应该进入其中一个case中。我使用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,您是否会得到预期的结果? - alex
1
代码在我的火狐浏览器上运行良好,是否还涉及其他代码?你使用的是什么浏览器?你可能还想添加 var img=""; 因为它会尝试将两个操作数附加到一个字符串上,而由于你没有初始化img,它只变成了“未定义”。 :) - Gordon Gustafson
switch...case 使用严格比较,你正在将一个字符串与整数进行比较。 - Blazemonger
7个回答

12

那很奇怪... 确保 dir 是一个整数,尝试在 switch 之前执行此操作:

dir = parseInt(dir);

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


1
不需要使用 parseInt,一元运算符 + 是解决问题的方法:switch (+dir) { ... - Šime Vidas
你说得对,获取的数据似乎是字符串,所以只需添加parseInt并将case 1:更改为case '1':即可解决问题。 - Gustavo
1
你可以用许多不同的方式将其转换为整数,这只是代码风格的问题 :) 我更喜欢在进行转换时明确指出,而不是使用像+dir这样的东西,这可能会让非 JavaScript 程序员(或初学者)难以理解。 - AlfaTeK

3
我知道我来晚了,但我认为这对于那些不理解为什么“if”有效而“switch”无效的人可能很重要。也许没有人会看到这个答案,但我在搜索其他东西时发现了它,所以也许有人会发现这有帮助:

你的switch如下:

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",但在 "==="(全等)的领域里则不然。

2

使用数组而不是一长串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(' ');

或者使用闭包。

1
确保您首先将“dir”转换为int。这是一种更清晰的解决方案,但仍然无法解释用户遇到的问题。 :) - Gordon Gustafson
如果问题是dir是一个字符串,那么可以这样解决。请参考此Fiddle:http://jsfiddle.net/cAg58/ - rsp
  1. 必须使用 +=,不能使用 =
  2. 您可以去掉 .png 后缀以消除冗余。然后:img += arr[dir] + '.png';
- Šime Vidas
它不一定要是+=,因为img一开始总是一个空字符串。 - rsp

2

我猜测有些原因导致dir作为一个字符串被传递进来了。尝试将case 1: 改为 case '1':


0

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

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

第一个代码做得正确,而接下来的两个却输入了"default"。它们是字符串而不是整数,而这正是对应的情况所期望的。我加上了


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

然后只有中间那个输入了 default。显然你调用函数的方式存在问题,很可能是传递了一个字符串。 我也使用了你的 if-else 语句块(添加了一个 else{alert(dir);}),这样每次调用都返回了正确的值。

Javascript 可以在字符串和整数(以及其他类型)之间实现即时转换(我认为还有更好的词可以描述它)。当你使用 == 进行比较时,就会发生这种情况。如果你将 ifs 中的比较改为 ===,就会得到与 switch 块相同的行为。


0

我将您的代码粘贴到一个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不执行隐式转换而==执行。


0
很难解释为什么,但是default:情况也需要像所有其他情况一样在其后加上break;语句。

3
虽然这是最后一个,但并不一定需要,但为了易读性,将其包含进去仍然是一个好主意。 - Matti Virkkunen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接