JavaScript Refactoring in Action: Replace Nested If-Else with Guards

Lars Grammel
Lars Grammel
Published on September 29, 2021

Nested if-else statements can make it unnecessarily complicated to reason about the different executions paths and results of a function. A loss of productivity and the introduction of bugs due to misunderstandings can be the outcome.

The refactoring "Replace Nested Conditional with Guard Clauses" from Martin Fowler's book "Refactoring - Improving the Design of Existing Code (2nd Edition)" can help in those situations.

A guard clause checks for a condition and returns from the function if the condition is true, potentially doing some computation and returning a result. It makes it easier to reason about the function by ending one execution path early.

Here is an example function (from Replace Nested Conditional with Guard Clauses, Martin Fowler) before refactoring:

function getPayAmount() {
  let result;
  if (isDead)
    result = deadAmount();
  else {
    if (isSeparated)
      result = separatedAmount();
    else {
      if (isRetired)
        result = retiredAmount();
      else
        result = normalPayAmount();
    }
  }
  return result;
}

In this example, three nested if-else statements check different conditions (e.g., isSeparated) and update a variable result. The variable is returned at the end of the function.

The goal is to refactor the function into the following version:

function getPayAmount() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retiredAmount();
  return normalPayAmount();
}

The refactored function uses guard clauses instead of nested if-else statements. The variable result is not necessary anymore and has been removed. The refactored code is easier to understand because there is less state (no variable) and each execution path returns early.

How can the original function be refactored step-by-step?

You can simplify the original code by applying two refactorings to each condition:

  • Inline return converts a variable assignment to a return statement. Such a conversion is possible when the following statement after the assignment in the control flow returns the variable.
  • Convert if-else to guard clause changes an if-else statement with return statements inside into to guard clauses, removing the indentation around the else block.

You can carry out these steps manually or with automation. The P42 JavaScript Assistant for VS Code is a refactoring tool that supports both operations. P42 indicates improvement opportunities with blue squiggly underlines. With refactoring automation, the code can be improved in a matter of seconds. After a final formatting step, the function has been refactored into the simplified version.

Here is how refactoring the code looks like in VS Code with P42:

Refactor "Replace Nested Conditional with Guard Clauses" Example

Refactoring is essential for maintaining a healthy codebase, and many small improvements go a long way. By introducing guard clauses, you can often simplify nested if-else statements and make your codebase a little bit better.

Happy refactoring!