How to Eliminate Complex Conditionals for Cleaner JavaScript Code
This article explains why complex conditional statements hurt code readability and maintainability, and provides practical techniques—such as avoiding flag parameters, encapsulating conditions, using guard clauses, applying the Null Object pattern, leveraging polymorphism, and employing strategy or command patterns—to simplify JavaScript/TypeScript code and improve overall quality.
Complex conditional statements make code hard to understand and increase maintenance cost; they also indicate high coupling. To improve code quality, avoid writing complex conditionals.
Do Not Use Flags as Function Parameters
Avoid using flag arguments; instead create separate functions for each distinct behavior.
function book(customer, isPremium) {
// ...
if (isPremium) {
premiumLogic();
} else {
regularLogic();
}
} function bookPremium(customer) {
premiumLogic();
}
function bookRegular(customer) {
regularLogic();
}Encapsulate Conditional Logic
Wrap conditions in well‑named functions to make the intent clear.
if (platform.state === 'fetching' && isEmpty(cart)) {
// ...
} function showLoading(platform, cart) {
return platform.state === 'fetching' && isEmpty(cart);
}
if (showLoading(platform, cart)) {
// ...
}Replace Nested Conditions with Guard Clauses
Use early returns to avoid deep nesting, eliminating the need for else keywords.
function getPayAmount() {
let result;
if (isDead) {
result = deadAmount();
} else {
if (isSeparated) {
result = separatedAmount();
} else {
if (isRetired) {
result = retiredAmount();
} else {
result = normalPayAmount();
}
}
}
return result;
} function getPayAmount() {
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
}Null Object Pattern
Instead of repeatedly checking for null, provide an object that implements the same interface but performs no action.
class Dog {
sound() { return 'bark'; }
}
['dog', null].map(animal => {
if (animal !== null) {
sound();
}
}); class Dog {
sound() { return 'bark'; }
}
class NullAnimal {
sound() { return null; }
}
function getAnimal(type) {
return type === 'dog' ? new Dog() : new NullAnimal();
}
['dog', null].map(animal => getAnimal(animal).sound()); // Returns ["bark", null]Use Polymorphism to Remove Conditionals
Replace switch or if chains with class hierarchies where each subclass implements its own behavior.
function Auto() {}
Auto.prototype.getProperty = function () {
switch (type) {
case BIKE:
return getBaseProperty();
case CAR:
return getBaseProperty() - getLoadFactor();
case BUS:
return (isNailed) ? 0 : getBaseProperty(voltage);
}
throw new Exception("Should be unreachable");
}; abstract class Auto {
abstract getProperty();
}
class Bike extends Auto {
getProperty() { return getBaseProperty(); }
}
class Car extends Auto {
getProperty() { return getBaseProperty() - getLoadFactor(); }
}
class Bus extends Auto {
getProperty() { return (isNailed) ? 0 : getBaseProperty(voltage); }
}
// client code
speed = auto.getProperty();Use Strategy or Command Patterns to Remove Conditionals
Encapsulate varying behavior in separate strategy objects or command functions.
function logMessage(message = "CRITICAL::The system ...") {
const parts = message.split("::");
const level = parts[0];
switch (level) {
case 'NOTICE':
console.log("Notice");
break;
case 'CRITICAL':
console.log("Critical");
break;
case 'CATASTROPHE':
console.log("Catastrophe");
break;
}
} const strategies = { criticalStrategy, noticeStrategy, catastropheStrategy };
function logMessage(message = "CRITICAL::The system ...") {
const [level, messageLog] = message.split("::");
const strategy = `${level.toLowerCase()}Strategy`;
const output = strategies[strategy](messageLog);
}
function criticalStrategy(param) { console.log("Critical: " + param); }
function noticeStrategy(param) { console.log("Notice: " + param); }
function catastropheStrategy(param) { console.log("Catastrophe: " + param); }
logMessage();
logMessage("CATASTROPHE:: A big Catastrophe");Summary
To improve code quality, avoid complex conditionals by not using flag parameters, encapsulating conditions, applying guard clauses, employing the Null Object pattern, leveraging polymorphism, and using strategy or command patterns.
Do not use flags as function parameters
Encapsulate conditional logic
Replace nested conditions with guard clauses
Apply the Null Object pattern
Use polymorphism to avoid conditionals
Use the Strategy pattern to avoid conditionals
Use the Command pattern to avoid conditionals
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
