Reputation: 311
well i have this trouble and ive been dealing with but i just cant get it to work
i have this function
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;
}
quite simple right? now i have this interval set to 5000 ms to call getDirections(variable), the function works well the first time its called but after that , it always enter in the default clause and it also alerts the 'entered default but direction=dirvalue' , i mean even if dir is a value between 0-7 it will always enter to default: but it would alert the value so it was supossed to enter to one of the cases.
i made the same using else if and it worked so i dont know what its wrong with 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';}
Upvotes: 3
Views: 14273
Reputation: 3607
I know I'm a bit late to the party, but I thought it might be important for anyone who doesn't understand why the "ifs" worked and the switch didn't. It's likely no one will read this answer, but I found it while searching for something else, so perhaps someone will find this helpful anyway:
Your switch is this:
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;
}
This is not the same as a series of double equals (==) but a series of triple equals (===). It would be equivalent to:
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);
}
In the world of "==", the integer 2 IS the same as the string "2", but not in the land of "===".
Upvotes: 3
Reputation: 111374
Using an array instead of a chain of if/else blocks or a giant switch statement will be faster, more flexible and less error-prone. Also, you wouldn't have to worry if dir
is a number or a string. Instead of:
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';}
you can store the file names in an array:
var images = [
'N.png', 'NE.png', 'E.png', 'SE.png', 'S.png', 'SO.png', 'O.png', 'NO.png'
];
or arguably more readable:
var images = "N.png NE.png E.png SE.png S.png SO.png O.png NO.png".split(' ');
and then use just:
img = images[dir];
Full implementation of getDirections using an array would be:
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;
}
Does it work for you?
If images
is used only in that one function then you may want to store it as a property of the function to avoid your namespace pollution like this:
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(' ');
or use a closure.
Upvotes: 2
Reputation: 4388
I pasted your code into an HTML file and ran it with the following buttons:
<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>
When calling the switch-version with a plain 2
, it works as expected. Calling it with '2'
makes it drop through to the default
line. The if-else version works as expected in both cases. So the issue is probably that switch
doesn't do an implicit conversion and ==
does.
Upvotes: 0
Reputation: 6424
I just ran the code in FireFox/FireBug and called the function this way
getDirections(0);
getDirections('1');
getDirections("2");
The first one does it correctly and the next two enter default
.
They are strings and not integer which is what the cases are looking for.
I added
case "2":
img+='NO2.png';
break;
and then only the middle one entered the default
. Obviously there is an issue with the way you are calling the function. It is likely passing a string.
I also used your if-else
block (added an else{alert(dir);}
and that returned the correct value for each call.
Javascript can do on the fly conversion (I think there's a better word for that) between strings and ints (and others). This is occuring when you do the comparrison using ==
. If you change the comparison in the ifs
to ===
you get the same behavior as with the switch
block.
Upvotes: 0
Reputation: 12459
I'd guess that for some reason dir is being passed in as a string. Try changing case 1: to case '1':
Upvotes: 2
Reputation: 7765
That is weird... try to make sure that dir is an int, do this before the switch:
dir = parseInt(dir);
If the alert shows the value correctly it should enter the switch, but still it can "look" correct but be of a different data type. Do the conversion manually to ensure it's an int
Upvotes: 12
Reputation: 1777
Hard to explain why, but the default:
case also need a break;
statement after it like all the other cases.
Upvotes: 0