Write Better If Statements
Here is an example of a wild if
statement that I found in my codebase. Let’s make it better!
if (!inventory || !inventory.config.can_check_stock || !inventory.status.is_real_time_stock_online) {
return;
}
One Condition Per Line
When the conditions exceed the 80–120 character limit, I will break the statement down into multiple lines.
I use split view in Webstorm a lot and this lets me read the code without scrolling left and right. I have a 1440p monitor and I wear glasses.
if (!inventory ||
!inventory.config.can_check_stock ||
!inventory.status.is_real_time_stock_online) {
return;
}
Standalone Parenthesis
If I have to break the statement into multiple lines, I will put the parenthesis in their own line (pun intended). This allows me to scan quickly and find the conditions faster.
I know this seems like a waste of space, and it definitely took me a while to get used to but it makes reading code so much faster. I will swear by it.
if (
!inventory ||
!inventory.config.can_check_stock ||
!inventory.status.is_real_time_stock_online
) {
return;
}
Logical Operators at the Front
Move the logical operators to the front, you will thank me! It makes it so much easier for me to understand if we are dealing with “AND”s or “OR”s.
if (
!inventory
|| !inventory.config.can_check_stock
|| !inventory.status.is_real_time_stock_online
) {
return;
}
Also, I like how it allows me to add an extra condition by simply duplicating the line and changing the condition. Otherwise, I will have to add the operator to the previous line and then add the condition at the bottom. -- Confessions of a Lazy Programmer
if (
!inventory
|| !inventory.config.can_check_stock
|| !inventory.status.is_real_time_stock_online // <-- duplicate this line
|| !inventory.status.is_real_time_pricing_online // <-- update this condition
) {
return;
}
Never Mix Logical Operators
Seriously, I go out of my to never mix && and || operators in the same if statement. This has caused me many grievances, and even after years of coding, it’s still easy to introduce unintended bugs.
For example, the following line may look fine, but it will error if the inventory object is null. We wanted to see if either the real-time pricing or real-time stock is online.
if (
inventory
&& inventory.status.is_real_time_pricing_online
|| inventory.status.is_real_time_stock_online
) {
return;
}
Skill issues — I know. Here are two techniques I use to cope with my skill issues.
Technique #1: Divide and Conquer
if (!inventory) {
return
}
if (
inventory.status.is_real_time_pricing_online
|| inventory.status.is_real_time_stock_online
) {
// Do something
}
Technique #2: Use Variables
const isRealTimePricingOnline = inventory && inventory.status.is_real_time_pricing_online;
const isRealTimeStockOnline = inventory && inventory.status.is_real_time_stock_online;
if (isRealTimePricingOnline || isRealTimeStockOnline) {
// Do something
}
Technique #3: Invert The Logic
Honestly, inverting the logic and doing early returns lends itself to a much more readable code. Instead of checking for a condition to be true so that I can execute a set of logic, I prefer to just check for conditions that are false and return early.
if (
inventory
&& !inventory.status.is_real_time_pricing_online
&& !inventory.status.is_real_time_stock_online
) {
return;
}
Special Case: Existential Operators
Yes — we could have simply done it like this for this particular example but hey, not all languages have them!
if (
inventory?.status.is_real_time_pricing_online
|| inventory?.status.is_real_time_stock_online
) {
// Do something
}
Avoid Extracting Into Variables
Finally, I avoid extracting conditions into a variable like the example below. It may feel like the variable version is more “self-documenting” compared to the direct version, but this just adds more mental complexity.
Having the condition in line with the if statement is easier to read and maintain.
Also, if you absolutely need to document it, a simple comment will do. Comments are not evil.
/** Varible Version */
const canCheckStock = inventory && inventory.config.can_check_stock;
const isRealTimeStockOnline = inventory && inventory.config.can_check_stock;
const isRealTimeStockAvailable = canCheckStock && isRealTimeStockOnline;
if (!isRealTimeStockAvailable) {
return;
}
/** Direct Version */
// Check to see if the real time stock information available.
if (
!inventory
|| !inventory.config.can_check_stock
|| !inventory.status.is_real_time_stock_online
) {
return;
}
Hope this helps!