EduFlow
JavaScript Fundamentals
0%

Section 2 · Logic and Functions

Making Decisions: if, else and Truthiness

17 min3 min readCode playground

Lesson at a glance

Make your program choose between paths with if, else if and else, combine conditions with &&, || and !, pick values with the ternary operator, and predict which values count as truthy or falsy.

  1. 1if, else if, else
  2. 2Combining conditions
  3. 3One value, many fixed options: switch
  4. 4The ternary: choosing a value
  5. 5Truthy and falsy

No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.

Pocket can add up what you spent. Now it should tell you how you are doing: fine, getting close to your budget, or over it. That means running different code depending on the data, which is what conditions are for.

if, else if, else

An if statement runs a block of code only when its condition is true:

JavaScript
const budgetCents = 2000;
const spentCents = 1750;

if (spentCents > budgetCents) {
  console.log("Over budget");
} else if (spentCents >= budgetCents * 0.8) {
  console.log("Close to your budget");
} else {
  console.log("On track");
}

The engine evaluates the first condition, 1750 > 2000, gets false, and moves on. The second, 1750 >= 1600, is true, so that block runs, and the rest of the chain is skipped. The else block runs only when every condition above it was false. At most one block in a chain ever runs.

Flow of the budget check: first test spent greater than budget; if yes print Over budget. If no, test spent at least 80 percent of budget; if yes print Close. If no, print On track. spent > budget? spent ≥ 80%? "On track" "Over budget" "Close" true: stop true: stop false false
An if chain stops at the first true condition

Because the first true condition wins, order matters. Put the narrowest case first. If you checked “at least 80%” before “over budget”, an over-budget month would also be at least 80%, and you would never see the “Over budget” message. The quiz below has exactly that bug.

The curly braces mark a block, a group of statements that run together. For a one-line body the braces are technically optional, but always write them: adding a second line later without braces is a classic bug where only the first line is conditional.

Combining conditions

Three logical operators let you build bigger conditions:

  • a && b (and) is true only when both are true.
  • a || b (or) is true when at least one is true.
  • !a (not) flips true to false and back.
JavaScript
const amountCents = 12500;
const category = "travel";
const isWeekend = false;

if (amountCents > 10000 && category !== "rent") {
  console.log("Big purchase: ask yourself twice");
}
if (category === "food" || category === "travel") {
  console.log("Flexible spending");
}
if (!isWeekend) {
  console.log("Weekday");
}

&& is evaluated before ||, just as * is before +. When you mix them, add parentheses so nobody, including future you, has to remember that.

One value, many fixed options: switch

When you compare a single value against a list of exact options, such as a category, a chain of else if (category === …) gets repetitive. The switch statement is built for that case:

JavaScript
const category = "travel";
let monthlyLimit;

switch (category) {
  case "food":
    monthlyLimit = 40000;
    break;
  case "travel":
  case "fun":
    monthlyLimit = 15000;
    break;
  default:
    monthlyLimit = 10000;
}
console.log(monthlyLimit);

switch compares with ===, jumps to the first matching case, and runs from there until it reaches a break. Forget a break and execution “falls through” into the next case, which is a frequent bug. Sometimes it is deliberate, as with "travel" and "fun" sharing one limit above. default runs when nothing matches, like a final else. For two or three conditions, or anything that is not a simple equality check, stay with if.

The ternary: choosing a value

Often you do not want to do different things, you want to pick between two values. The conditional operator, usually called the ternary, does that in one expression:

JavaScript
const spent = 2100;
const budget = 2000;
const status = spent > budget ? "Over budget" : "On track";
console.log(status);

Read it as “if spent > budget, then "Over budget", otherwise "On track"”. Because the ternary produces a value, you can store it in a const or drop it into a template literal. Use it for two outcomes. For three or more, an if chain reads better than nested ternaries.

Truthy and falsy

A condition does not have to be a boolean. JavaScript accepts any value and converts it: values that count as true are truthy, values that count as false are falsy. The falsy list is short enough to memorise:

false, 0, -0, 0n, "" (empty string), null, undefined, NaN.

Everything else is truthy, including some that surprise people: "0", "false", " " (a space), and empty lists and objects.

JavaScript
const note = "";
if (note) {
  console.log("Has a note");
} else {
  console.log("No note");
}
console.log(Boolean("0"), Boolean(0), Boolean(" "));

Truthiness makes checks like if (note) short and readable for strings, where “empty” and “missing” both mean “nothing to show”. It is risky for numbers, where 0 is often a real, valid value.

&& and || also work with non-boolean values: they return one of their operands. name || "Anonymous" gives name if it is truthy and "Anonymous" otherwise, which is a common way to supply defaults. It has the same zero problem, which is why JavaScript added a better operator for defaults, ??, coming up in section 3.

Conditions let Pocket react to one value. Next you will make it handle many values, one after another, with loops.

Key takeaways

  • An if chain checks conditions top to bottom and runs only the first block whose condition is true, so put the most specific case first.
  • && needs both sides true, || needs at least one, and ! flips a boolean.
  • [object Object]
  • Only eight values are falsy (false, 0, -0, 0n, "", null, undefined, NaN); everything else, including "0" and [], is truthy.

Further reading

Check your understanding

4 questions

Question 1 of 4

With spent = 2100 and budget = 2000, what does this log?

JavaScript
if (spent > budget * 0.8) {
  console.log("close");
} else if (spent > budget) {
  console.log("over");
} else {
  console.log("ok");
}
Question 2 of 4

Which of these values is truthy?

Question 3 of 4

A user can set a daily limit, and 0 is a valid choice meaning “no spending today”. What does const limit = userLimit || 5000; do when userLimit is 0?

Question 4 of 4

Which line best uses the ternary operator?

Practice

Code playground

Is Pocket on budget?

Fill in budgetStatus(spentCents, budgetCents) so it returns "over" when spending is more than the budget, "close" when it is at least 80% of the budget (but not over), and "ok" otherwise. Spending exactly the budget counts as "close", not over.

Then fill in amountLabel(amountCents) with a ternary: return "big" for 10000 cents ($100) or more, and "small" otherwise. Writing return followed by a value hands that value back to whoever called the function.

// The function wrapper is written for you (functions get their own lesson soon).
// spentCents and budgetCents arrive as numbers. Use if / else if / else
// and `return` the status string.
function budgetStatus(spentCents, budgetCents) {
  return "ok";
}

// Use a ternary to pick the label for one value
function amountLabel(amountCents) {
  return "";
}

console.log(budgetStatus(1750, 2000));
console.log(amountLabel(12500));
Loading the editor…

Ctrl/⌘ + Enter to run · Runs in a sandbox in your browser. Nothing leaves your device.

Console

(no output)

Checks

  • Returns “over” when spending is more than the budget
  • Returns “close” from 80% up to and including the budget
  • Returns “ok” below 80%
  • amountLabel returns “big” from 10000 cents and “small” below