15

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);
  }
}
chharvey
  • 8,580
  • 9
  • 56
  • 95
Starkemp315
  • 151
  • 1
  • 1
  • 4
  • 2
    No it's not compulsory to have else with an if. – Harry Joy Nov 09 '11 at 05:02
  • 1
    To my knowledge, there's no need to have an else in any language. If there's nothing special that you want to do when the if condition is false, there's no logical need for it either. It would be an empty block. – Toast Nov 09 '11 at 05:05
  • 2
    `else` is an optional keyword in `if/else` block. And, possible, that a logic of your tutorial code does not require `else` – Andrew D. Nov 09 '11 at 05:06
  • 1
    `else` is used where a catch-all is needed to take care of anything that wasn't evaluated as true. I have seen code that ends with `else if` and then give a condition that must be met. This is a way to only implement code branching if there are specific conditions that have to be met and you don't care about conditions outside the business logic. – Matteo Feb 26 '19 at 18:48

8 Answers8

20

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

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

linuxdan
  • 4,476
  • 4
  • 30
  • 41
Thilo
  • 257,207
  • 101
  • 511
  • 656
  • That's what I figured, but I haven't seen any official documentation. Even [MDN's docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) always have a final else clause. Could you provide some references? – chharvey Jul 22 '16 at 23:43
7

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

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

//other stuff
Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
4

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.

Wazy
  • 8,822
  • 10
  • 53
  • 98
2

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.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • It's doubly unnecessary since the last `break` statement is encouraged, but serves absolutely no purpose. – puk Nov 09 '11 at 08:58
1

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.

linuxdan
  • 4,476
  • 4
  • 30
  • 41
0

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.

Stephen
  • 1,737
  • 2
  • 26
  • 37
Serdalis
  • 10,296
  • 2
  • 38
  • 58
-2

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.

James.Xu
  • 8,249
  • 5
  • 25
  • 36
  • but **not** required (and that was the question) – Aziz Nov 09 '11 at 05:05
  • 4
    Can you explain why you think it is a good habit? I can't think of any common problem it catches. – O'Rooney Nov 09 '11 at 05:13
  • tell the people who checks your code that "i didnt miss the else part, there is indeed nothing to do in the else" – James.Xu Nov 09 '11 at 05:26
  • It catch when curScene get an unexpected value because of whatever changes in other parts of the code or environment, the same way "default" catch unexpected conditions in "switch" (see http://stackoverflow.com/questions/4649423/should-switch-statements-always-contain-a-default-clause) – Alexandre Morgaut Nov 16 '16 at 14:27
-4

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

Nagendra
  • 1
  • 1
  • 2
    Welcome to [so]. In this case, the code provided works perfectly fine -- the questioner's just asking why is `else` *not* necessary in that example. – Qantas 94 Heavy Mar 15 '14 at 08:05