Hugo JS

Why you should Stop using the ‘else’ keyword in JavaScript

If-else keyword built into nearly every programming language and simple conditional logic are easy for anyone to understand. If you are a programmer, you know else keyword. But if you are a good programmer, don’t use this keyword. One of the biggest mistakes I fell into when starting was overusing the else keyword when writing conditionals. Let me explain!

Why

Think about what else means, it means “if A then this, if not A then that;”. This isn’t a problem if A is binary — the problem space is only 2 cases. But if A is a combination of binary variables, or contains larger variables, your negative problem space can be unexpectedly large and difficult to understand, test and maintain. To avoid if/else if, to only use if statements, to spend the time to ensure the entry criteria for your group of if’s are mutually exclusive so that the answers don’t depend on the order of execution.

  • It promotes the main execution lane, with a few special cases.
  • It forces us to write all conditions, required to process the data, at the beginning of each function.
  • Use a switch — case statement.
  • Use polymorphism to handle complex conditional cases, making the code more clear like State Pattern.

Example

Our example is a traffic light (i.e. TrafficLight object) with 3 different states: Red, Yellow and Green, each with its own set of rules. The rules go like this:

  • Say the traffic light is Red. After a delay the Red state changes to the Green state.
  • Then, after another delay, the Green state changes to the Yellow state.
  • After a very brief delay the Yellow state is changed to Red.
  • And on and on.

Don’t use if-else keyword

const LightState = {
  GREEN: 0,
  YELLOW: 1,
  RED: 2
}

var TrafficLight = function () {

  var count = 0

  // default state = red
  var currentState = 0;

  this.change = function(state) {
    if (count++ >= 10 ) return
    currentState = state
    this.go(currentState)
  }
  this.go = function(state) {
    if (currentState == LightState.GREEN) {
      console.log("Green --> for 1 minute")
      this.change(LightState.YELLOW)
    } 
    else if (currentState == LightState.YELLOW) {
      console.log("Yellow --> for 10 seconds")
      this.change(LightState.RED)
    } else if (currentState == LightState.RED) {
      console.log("Red --> for 1 minute");
      this.change(LightState.GREEN)
    } else {
      throw Error("Invalid State")
    }
  }
  this.start = function() {
    this.change(LightState.GREEN)
  }
}

The simple way

We only remove else keywords and re-write all conditions.

this.go = function (state) {
    if (currentState == LightState.GREEN) {
      console.log("Green --> for 1 minute")
      this.change(LightState.YELLOW)
    }
    if (currentState == LightState.YELLOW) {
      console.log("Yellow --> for 10 seconds")
      this.change(LightState.RED)
    }
    if (currentState == LightState.RED) {
      console.log("Red --> for 1 minute");
      this.change(LightState.GREEN)
    }
    if (currentState != LightState.GREEN && currentState != LightState.RED && currentState != LightState.YELLOW) {
      throw Error("Invalid State")
    }
}

Or we can use a switch instead of if-else. A switch looks much cleaner when you have to combine cases. A if-else will quickly get out of control.

this.go = function (state) {
    switch (state) {
      case LightState.GREEN:
        console.log("Green --> for 1 minute")
        this.change(LightState.YELLOW)
        break
      case LightState.YELLOW:
        console.log("Yellow --> for 10 seconds")
        this.change(LightState.RED)
        break
      case LightState.RED:
        console.log("Red --> for 1 minute");
        this.change(LightState.GREEN)
        break
      default:
        throw Error("Invalid State")
    }
  }

We can use the State Pattern to remove all if-else keyword in these codes

Here, we introduce lots of if-else blocks/switch statements to guard the various conditions. The state pattern¹ fits in such a context. It allows your objects to behave differently based on the current state, and you can define state-specific behaviors. In this pattern, we start thinking in terms of possible states of our traffic light, and you segregate the code accordingly.

  • For a state-specific behavior, you have separate objects.
  • Operations defined in the traffic light are delegating the behavior to the current state’s object.
  • States are triggering state transitions themselves.

Traffic Light: Green (1 minute) → Yellow (10 seconds)→ Red (1 minute)

var TrafficLight = function () {

    var count = 0

    // default state = green
    var currentState = new Green(this);

    this.change = function (state) {
        // limits number of changes
        if (count++ >= 10) return;
        currentState = state;
        currentState.go();
    }
    this.start = function () {
        currentState.go();
    }
}

var Red = function (light) {
    this.light = light

    this.go = function () {
        console.log(("Red --> for 1 minute"))
        light.change(new Green(light));
    }
}

var Yellow = function (light) {
    this.light = light;
 
    this.go = function () {
        console.log("Yellow --> for 10 seconds")
        light.change(new Red(light));
    }
};

var Green = function (light) {
    this.light = light;
 
    this.go = function () {
        console.log("Green --> for 1 minute");
        light.change(new Yellow(light));
    }
};

They are print the same output as following

Green → for 1 minute
Yellow → for 10 seconds
Red → for 1 minute
Green → for 1 minute
Yellow → for 10 seconds
Red → for 1 minute
Green → for 1 minute
Yellow → for 10 seconds
Red → for 1 minute
Green → for 1 minute
Yellow → for 10 seconds

It is these examples of bad codes and good codes. Finally, thanks for reading and hopefully I’ve covered everything.

#javascript #javascript tips #coding #programming

Why you should Stop using the ‘else’ keyword in JavaScript
322.95 GEEK