Conditionals
if/else, ternary, logical operators as control flow, and switch's non-obvious fallthrough.
Conditionals branch execution based on whether an expression is truthy or falsy.
if/else is the fundamental branch. The else if chain handles multiple cases.
const score = 72;
if (score >= 90) {
console.log("A");
} else if (score >= 80) {
console.log("B");
} else {
console.log("C or below");
}
// C or belowThe ternary operator condition ? a : b is a compact inline branch - appropriate for simple value selection, not for nesting logic.
const age = 20;
const label = age >= 18 ? "adult" : "minor";
console.log(label); // adult|| returns the first truthy operand (or the last value if all are falsy); && returns the first falsy operand (or the last value if all are truthy). ?? (nullish coalescing) returns the right side only when the left is null or undefined - unlike ||, it does not treat 0 or "" as missing.
const requestedLimit = 0;
const withOr = requestedLimit || 100; // 100 - wrong! 0 is falsy
const withNull = requestedLimit ?? 100; // 0 - correct
console.log(withOr); // 100
console.log(withNull); // 0switch matches by strict equality. Without a break, execution falls through into the next case - a common source of bugs.
const status = "pending";
switch (status) {
case "pending":
console.log("queued");
// no break - falls through to "active"!
case "active":
console.log("running");
break;
case "done":
console.log("finished");
break;
default:
console.log("unknown");
}
// queued
// runningIn production
The || defaulting pattern - const host = config.host || "localhost" - silently swallows legitimate falsy values like 0, "", and false. This bites feature-flag evaluations, counter initializations, and port numbers. Default to ?? for optional config and only reach for || when you genuinely want to treat all falsy inputs as absent.
Enjoyed this? Get more essays on software craft delivered to your inbox.
Subscribe free