You should consider refactoring your code if you come to a point where you think you need an else statement.
Avoiding else statements helps to keep your cyclomatic complexity down, and assists in adhering to the single responsibility principle.
How an else statement can be refactored away depends on what the if statement is trying to achieve and where it is located.
Conditional variable assignment
A conditional variable assignment can be refactored into a default value and a single if block.
var someVariable;
if(someCondition){
someVariable = 'First';
} else {
someVariable = 'Second';
}
Would become
var someVariable = 'First';
if(someCondition) someVariable = 'Second';
The long statement
If statements that span a lot of lines can become difficult to understand with else statements.
function doSomething(){
if(isLoggedIn){
//50 lines of code
}else{
//50 different lines of code
}
}
Removing the else statements makes it more clear what exactly is going on because each block describes what it does.
Another benefit is that it makes it easier for you to chop and change the function contents because each block is independent.
function doSomething(){
if(loggedIn){
//50 lines of code
}
if(!loggedIn){
//50 different lines of code
}
}
In addition to removing the else statements, you should also consider splitting your code out into separate function calls or classes that describe each step and reduce the number of lines in a single block.
The conditional return value
This one is very similar to the conditional variable assignment and usually starts the same way.
function calculateScore(roll){
var score;
if(roll == 1){
score = 5;
}else{
score = 10;
}
return score;
}
To remove the else, you break away execution when you know enough to return the correct result.
This makes it easier to know when you can forget about this function as you are trying to understand what is going on in the application.
function calculateScore(value){
var rollIsOne = roll == 1;
if(rollIsOne) return 5;
if(!rollIsOne) return 10;
}
A function can usually be refactored into this format quite easily when it is only doing one thing. If you can’t see a way to refactor it, it may be that the function is doing too much.
Nested else statements
Nested else statements can become a confusing mess, especially in loops.
var specialNumbers = [];
var regularNumbers = [];
var oddPrimeNumbers = [];
for(var i = 0; i < 100; i++){
var num = inputNumbers[i];
if(isNumberPrime(num)){
if(numberIsEven(num)){
specialNumbers.push(num);
}else{
oddPrimeNumbers.push(num);
}
}else{
regularNumbers.push(num);
}
}
This horrible mess can be refactored in a much more readable way by removing the else statements and adding in a few variables.
Without parsing the above code in your brain, you’d have no idea what a “special number” was.
With the refactored code below it basically screams it at you.
This may seem like a trivial difference, but it becomes significant in real world situations where the logic is much more complex.
var specialNumbers = [];
var regularNumbers = [];
var oddPrimeNumbers = [];
for(var i = 0; i < 100; i++){
var num = inputNumbers[i];
var numberIsPrime = isNumberPrime(num);
var numberIsEven = num % 2 == 0;
var numberIsOddPrime = !numberIsEven && numberIsPrime;
var numberIsSpecial = numberIsPrime && numberIsEven;
if(numberIsSpecial){
specialNumbers.push(num);
continue;
}
if(numberIsOddPrime){
oddPrimeNumbers.push(num);
continue;
}
regularNumbers.push(num);
}
The “this must be a joke” conditional
Sometimes you may come accross the following
if(someCondition){
return true;
}else{
return false;
}
Or another variant
return someCondition ? true : false;
You might think think this is incredibly stupid, and you’d be right, but people still do it.
Simplified
return someCondition;
// Or if you are in javascript and need an actual bool
return !!someCondition;
What about the ternary operator?
The ternary operator is only acceptable to be used is situations with only 2 possible outcomes.
Here is a basic example of the ternary operator being used correctly.
function boolToString(bool isYes){
return isYes ? 'Yes' : 'No';
}
This usage is acceptable because it’s so blindingly obvious what the ternary operator is outputting.
If you have more than one ternary operator in a block, or god forbid nested ternary operators, you should probably think about refactoring into multiple branching if statements.
Further reading
Replace Nested Conditional with Guard Clauses - very good site with better examples on guard clauses.