Skip to content
Happy Programming Guide
Start learning
JavaScript

Practical Uses of One-Line If Else Statements in JavaScript

The ternary operator, logical AND and OR, and the nullish coalescing operator — what each one-liner is genuinely good for, and when a normal if is clearer.

A pen and an open notebook ready for notes

JavaScript gives you four ways to make a decision on one line: the ternary operator, &&, || and ??. Each is genuinely useful in a specific place, and each becomes unreadable when pushed past it. This guide shows where each earns its place and where a plain if is the better answer.

The ternary operator#

JavaScript
const status = age >= 18 ? "adult" : "minor";

Read it as: condition, then the value if true, then the value if false. The important difference from an if statement is that this is an expression — it produces a value, so it can go anywhere a value can go.

JavaScript
// In a template string
console.log(`You have ${count} item${count === 1 ? "" : "s"}`);

// As a function argument
setTimeout(save, isUrgent ? 0 : 5000);

// In an object literal
const config = {
  mode: isDev ? "development" : "production",
};

// As a return value
const label = (n) => n < 0 ? "negative" : n === 0 ? "zero" : "positive";

That last one is a chained ternary. Two levels reads fine when the values line up; three or more should be a switch or a lookup object.

The logical AND operator#

&& stops as soon as it finds something falsy and returns it; otherwise it returns the last value. That makes it a compact “only if” :

JavaScript
// Only calls the function if it exists
onSuccess && onSuccess(result);

// Only reads the property if the object exists
const city = user && user.address && user.address.city;

It is used constantly in JSX for conditional rendering:

JavaScript
{errors.length > 0 && <ErrorList items={errors} />}

OR for defaults, and where it goes wrong#

JavaScript
const name = input || "Anonymous";

This returns the first truthy value. The problem is that JavaScript treats several legitimate values as falsy:

JavaScript
const count = 0 || 10;          // 10  - wrong, 0 was a real value
const label = "" || "Untitled"; // "Untitled" - maybe wrong
const flag = false || true;     // true - definitely wrong

If zero, an empty string or false are valid values in your data, || silently replaces them.

Nullish coalescing#

?? only falls back when the left side is null or undefined:

JavaScript
const count = 0 ?? 10;              // 0    - correct
const label = "" ?? "Untitled";     // ""   - correct
const missing = undefined ?? 10;    // 10   - correct

The rule is simple: use ?? for defaults, and || only when you genuinely want every falsy value replaced.

JavaScript
// Settings, where 0 and false are meaningful
const timeout = settings.timeout ?? 3000;
const isEnabled = settings.enabled ?? true;
const volume = settings.volume ?? 0.5;

You cannot mix ?? with && or || without brackets — that is a syntax error on purpose, because the precedence would be ambiguous:

JavaScript
const value = a || b ?? c;      // SyntaxError
const value = (a || b) ?? c;    // fine

Optional chaining#

?. replaces the long && chains for property access:

JavaScript
const city = user?.address?.city;             // undefined if any step is missing
const first = list?.[0];                      // safe indexing
const result = callbacks.onDone?.();          // only calls if defined

// Combines naturally with ??
const city = user?.address?.city ?? "Unknown";

When to stop and write a normal if#

Three practical signals:

  • The line no longer fits comfortably on screen. Wrapping a ternary across four lines removes the only advantage it had.
  • The branches do things rather than produce values. That is what statements are for.
  • You had to think about precedence. If you needed brackets to be sure, the reader will need them too.
JavaScript
// Hard to follow
const result = a ? (b ? x : y) : (c ? z : w);

// Clearer
let result;
if (!a) {
  result = c ? z : w;
} else {
  result = b ? x : y;
}

For several discrete cases, a lookup object beats both:

JavaScript
const MESSAGES = {
  404: "Not found",
  403: "Not allowed",
  500: "Something went wrong",
};

const message = MESSAGES[status] ?? "Unexpected error";

Questions people ask#

Is the ternary operator slower than an if?

No. They compile to effectively the same thing. Choose on readability alone.

Can I use await inside a ternary?

Yes, inside an async function: const data = useCache ? cached : await fetchData();. It is legal, though an if is often clearer when one branch does real work.

What is the difference between ?? and ||= ?

?? chooses a value. ??= assigns only when the current value is null or undefined: options.retries ??= 3. There are matching ||= and &&= operators.

Does every browser support ?? and ?.

Every current browser does. If you must support older environments, a build step such as Babel or TypeScript converts them for you.

Where to go next#

JavaScript array methods, the reference worth bookmarkingRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *