JavaScript by Example

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 below

The 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); // 0

switch 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
// running

In 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