Starkemp315
Starkemp315

Reputation: 151

Why would Javascript `if...else if` not end with an `else`?

Here is a snippet of JavaScript code from a tutorial I was working with. I don’t understand why it doesn’t end with a final else clause; I thought that was a rule.

var curScene = 0;

function changeScene(decision) {
  var message = "";

  if(curScene == 1) {
    message = " welcome";
  } else if (curScene == 2) {
    message = " this is scene two";
  } else if (curScene == 3) {
    message = " this is scene three";
  }

  document.getElementById("sceneimg").src = "scene" + curScene + ".png";

  if(message != ""){
    alert(message);
  }
}

Upvotes: 15

Views: 24781

Answers (8)

Thilo
Thilo

Reputation: 262494

I thought it was always supposed to end with an "else"?

The else block is optional. You can have if without else.

Upvotes: 20

linuxdan
linuxdan

Reputation: 4854

Not having an else clause is fine syntactically. MDN Documentation Basically the second if becomes the body of the else, see the section on "how it would look like if the nesting were properly indented".

As to whether it's bad practice I think that depends on intent. By not explicitly defining the final else clause, you might end up with a bug where a condition you didn't cover comes through. Consider this:

if(myVariable > 0) {
   doSomething();
} else if(myVariable < 0) {
   doSomethingElse();
}

Nothing happens if myVariable is 0. It would be hard to see if you were just glancing through the code. I would say if you run into this pattern it would be a code smell, something might be wrong, but it could be fine.

The same logic could always be expressed with nested if statements. I would go with whatever is more readable.

Upvotes: 1

Nagendra
Nagendra

Reputation: 1

change the if condition for answer validation if(answer==100) to if(answer===100) it is working fine now...

Upvotes: -4

Serdalis
Serdalis

Reputation: 10489

else is a default case for the if statement. If there is no else then if none of the conditions in the if or else if cases are met than the if statment will do nothing.

Usually it is good practice to have a default case but there are a lot of times where it is not necessary and thus excluded from the code.

In this case, if the curScene was anything other than 1, 2, 3 then the else statment would be used, but since there is no processing to be done on other cases the coder has not included an else.

Upvotes: 0

Wasim Karani
Wasim Karani

Reputation: 8886

Consider 3 Scenario
Scenario 1: Boolean condition

if (condition) {}
else {}

Specifying a condition as else if would be redundant, and it's really obvious to the reader what the code does. There is no argument for using else if in this case.

Scenario 2: Infinite states

Here we are interested in testing for conditions A and B (and so on), and we may or may not be interested in what happens if none of them holds:

if (conditionA) {}
else if (conditionB) {}
else {} // this might be missing as it is in your case

The important point here is that there isn't a finite number of mutually-exclusive states, for example: conditionA might be num % 2 == 0 and conditionB might be num % 3 == 0.

I think it's natural and desirable to use a reasonable amount of branches here; if the branches become too many this might be an indication that some judicious use of OO design would result in great maintainability improvements.

Scenario 3: Finite states

This is the middle ground between the first two cases: the number of states is finite but more than two. Testing for the values of an enum-like type is the archetypal example:

if (var == CONSTANT_FOO) {}
else if (var == CONSTANT_BAR) {} // either this,
else {} // or this might be missing

In such cases using a switch is probably better because it immediately communicates to the reader that the number of states is finite and gives a strong hint as to where a list of all possible states might be found (in this example, constants starting with CONSTANT_). My personal criteria is the number of states I 'm testing against: if it's only one (no else if) I 'll use an if; otherwise, a switch. In any case, I won't write an else if in this scenario.

Adding else as an empty catch-errors block

This is directly related to scenario #2 above. Unless the possible states are finite and known at compile time, you can't say that "in any other case" means that an error occurred. Seeing as in scenario #2 a switch would feel more natural, I feel that using else this way has a bad code smell.

Use a switch with a default branch instead. It will communicate your intent much more clearly:

switch(direction) {
    case 'up': break;
    case 'down': break;
    default: // put error handling here if you want
}

This might be a bit more verbose, but it's clear to the reader how the code is expected to function. In my opinion, an empty else block would look unnatural and puzzling here.

Upvotes: 4

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324620

It doesn't have to, for the same reason an if on its own doesn't require an else.

Usually it's a good idea to have one, as a sort of "catch-all" situation, but the above code could be written as:

switch(curScene) {
    case 1: message = " welcome"; break;
    case 2: message = " this is scene two"; break;
    case 3: message = " this is scene three"; break;
}

In the above code, I could also add:

    default: message = " invalid curScene value"; break;

But it's completely optional to do so. It depends on how reliable the curScene variable is whether or not I personally would add it in.

Upvotes: 2

James.Xu
James.Xu

Reputation: 8295

yes, always have a else is VERY GOOD habit(when using with if-elseif). sometimes people might even write this:

if(curScene == 1) {
    message =" welcome";
else if (curScene == 2) {
    message = " this is scene two";
}
else if (curScene == 3) {
    message = " this is scene three";
} else {
    // empty.
}

to tell people there is indeed nothing to do in the else.

Upvotes: -2

Petar Ivanov
Petar Ivanov

Reputation: 93020

For the same reason as why you can have just a single if:

if( /*condition*/ ) {
    //some code
}

//other stuff

Upvotes: 7

Related Questions