Else If in JavaScript: Syntax, Examples, and Pitfalls

Oct 2, 2026·21 min read

You have a score of 92 and three possible labels. The order of your conditions decides whether JavaScript calls it a distinction, a pass, or something else entirely.

In JavaScript, write else if as two words to test conditions from top to bottom, run the first truthy branch, and skip the rest of the chain.

JavaScript Else If Syntax

An else if chain starts with one if, continues with zero or more else if clauses, and may finish with one else. Each condition goes inside parentheses, and each branch is a statement. These examples use recommended braces, even though JavaScript permits a single statement without them:

function classifyScore(score) {
  if (score >= 90) {
    return "distinction";
  } else if (score >= 75) {
    return "merit";
  } else if (score >= 60) {
    return "pass";
  } else {
    return "retry";
  }
}

console.log(classifyScore(82));
merit

The score fails score >= 90, passes score >= 75, and returns "merit". The two later branches do not run.

JavaScript has no one-word elseif keyword and no elif keyword. Write else if with a space. Syntactically, this works because the statement after else is another if statement, although developers normally read the connected structure as one chain.

One connected chainif (condition) { branch }else + if (condition)repeat this clause as neededoptional else { fallback }
An else-if chain has one required head, repeatable middle clauses, and an optional fallback.

The final else is optional. Use it when every remaining input belongs in one fallback branch. Leave it out when doing nothing is a valid result:

function warnAboutScore(score) {
  if (score < 0) {
    return "score is below zero";
  } else if (score > 100) {
    return "score is above 100";
  }

  return "score is in range";
}

console.log(warnAboutScore(74));
score is in range

Both explicit conditions are false, so execution continues after the chain. Conditional branching: if, ’?’ covers the wider if, else, and conditional-operator model.

How an Else If Chain Runs

An else if chain follows one rule: the first truthy condition wins.

JavaScript begins at the first if. If that condition is falsy, it moves to the next else if; if the condition is truthy, JavaScript runs that branch and skips every remaining clause in the chain.

score = 82score ≥ 90?falsyscore ≥ 75?truthymeritrunsTesting stops here≥ 60 and else are skipped
For 82, the first test fails, the second succeeds, and the remainder is skipped.

A branch tracer makes those decisions visible. This version requires Node.js, which makes command-line arguments available through process.argv. Save the program as branch-tracer.js, then pass a score with a command such as node branch-tracer.js 92:

function traceScore(score) {
  const checks = [
    { test: "score >= 90", matches: () => score >= 90, label: "distinction" },
    { test: "score >= 75", matches: () => score >= 75, label: "merit" },
    { test: "score >= 60", matches: () => score >= 60, label: "pass" },
  ];

  let selected = false;

  for (const check of checks) {
    if (selected) {
      console.log(`skipped ${check.test}`);
    } else if (check.matches()) {
      console.log(`tested ${check.test}: truthy`);
      console.log(`selected: ${check.label}`);
      selected = true;
    } else {
      console.log(`tested ${check.test}: falsy`);
    }
  }

  if (selected) {
    console.log("skipped else");
  } else {
    console.log("selected: retry");
  }
}

const argument = process.argv[2];
const score = argument === undefined ? 92 : Number(argument);

if (!Number.isFinite(score)) {
  console.log("enter a numeric score");
} else {
  traceScore(score);
}
tested score >= 90: truthy
selected: distinction
skipped score >= 75
skipped score >= 60
skipped else

The default score, 92, satisfies the first condition. The tracer marks that branch as selected and every later choice as skipped. Change the command-line value to 82, and the first test becomes falsy before score >= 75 selects "merit".

This stopping rule applies to the whole connected chain. It does not matter whether another condition farther down would also be truthy. Once one branch runs, selection is over.

That distinction matters when conditions overlap.

Condition Order Changes the Result

Range conditions often overlap. A score of 92 satisfies score >= 60, score >= 75, and score >= 90 at the same time, so their order determines which label wins.

One score, three matches0100broadscore ≥ 60score ≥ 75≥ 9092
The marker for 92 sits inside all three threshold ranges.

Put the broad passing condition first and the higher branches become unreachable for passing scores:

function classifyScoreWrong(score) {
  if (score >= 60) {
    return "pass";
  } else if (score >= 75) {
    return "merit";
  } else if (score >= 90) {
    return "distinction";
  } else {
    return "retry";
  }
}

console.log(classifyScoreWrong(92));
console.log(classifyScoreWrong(82));
pass
pass

Both scores match score >= 60, so JavaScript returns "pass" without testing either higher threshold. The syntax is valid. The classification is not.

For these overlapping >= thresholds, place the highest threshold first and work downward:

function classifyScore(score) {
  if (score >= 90) {
    return "distinction";
  } else if (score >= 75) {
    return "merit";
  } else if (score >= 60) {
    return "pass";
  } else {
    return "retry";
  }
}

console.log(classifyScore(92));
console.log(classifyScore(82));
console.log(classifyScore(64));
console.log(classifyScore(48));
distinction
merit
pass
retry

Each condition now describes the highest remaining category. By the time JavaScript tests score >= 75, it already knows the score is below 90. By the time it reaches score >= 60, it already knows the score is below 75.

High-to-low ordering is required for this particular pattern because the >= ranges overlap. It is not a universal rule for every chain. Conditions that do not overlap can use any order that preserves the intended result, while conditions with side effects deserve a redesign instead of clever ordering.

The general rule is narrower: when several conditions can match the same input, put the branch that should win first.

Comparison details such as >=, strict equality, and string ordering are covered in Comparisons.

What Counts as True or False

An if condition does not need to produce the literal Boolean value true. JavaScript converts the condition to a Boolean, then chooses a branch from that result. This use of a value is called a Boolean context.

The complete falsy set is short:

  • false
  • undefined
  • null
  • NaN
  • positive and negative numeric zero, including 0 and -0
  • 0n
  • the empty string, ""
  • the legacy browser value document.all

Every other value is truthy. That includes some values that can look empty:

const values = [
  ["nonempty string", "false"],
  ["empty array", []],
  ["empty object", {}],
  ["zero", 0],
  ["empty string", ""],
];

for (const [name, value] of values) {
  if (value) {
    console.log(`${name}: truthy`);
  } else {
    console.log(`${name}: falsy`);
  }
}
nonempty string: truthy
empty array: truthy
empty object: truthy
zero: falsy
empty string: falsy

The string "false" contains characters, so it is truthy. Empty arrays and empty ordinary objects are still objects, and objects are truthy in Boolean contexts.

Boolean contextBoolean(value)truthy“false”[ ] and { }“0”falsynumber 0empty string
Values that look empty or false can still enter the truthy side.

This catches form handling code. A text field containing "0" is truthy because it contains one character, while the number 0 is falsy:

function describeGuests(guests) {
  if (guests) {
    return "guest value is truthy";
  } else {
    return "guest value is falsy";
  }
}

console.log(describeGuests("0"));
console.log(describeGuests(0));
guest value is truthy
guest value is falsy

When you need a particular meaning, test it directly. guests === 0, name.length === 0, and items.length > 0 state three different intentions. A bare truthiness check folds those meanings together.

Logical operators explains how the same Boolean conversion affects &&, ||, and !.

Else If Versus Separate If Statements

An else if chain performs mutually exclusive selection: at most one branch runs. Separate if statements perform independent tests: each condition is tested if control reaches it, and multiple truthy bodies can run unless an earlier body redirects control flow.

Use the same score, 92, in both structures to expose the difference:

const score = 92;

if (score >= 90) {
  console.log("chain: distinction");
} else if (score >= 75) {
  console.log("chain: merit");
} else if (score >= 60) {
  console.log("chain: pass");
}

if (score >= 60) {
  console.log("independent: passed");
}

if (score >= 75) {
  console.log("independent: merit threshold reached");
}

if (score >= 90) {
  console.log("independent: distinction threshold reached");
}
chain: distinction
independent: passed
independent: merit threshold reached
independent: distinction threshold reached

The chain chooses one label. The standalone statements report all milestones the score reached.

else if chainseparate ifsscore 92distinctionstopone resultscore 92passmeritdistinctionall three tests match
A chain selects one outcome; independent if statements can activate several outcomes.

Neither structure replaces the other. If a customer can receive one shipping category, use a chain. If the same order can require an address check, an age check, and a stock check, use independent statements because several actions may apply.

Say you accidentally connect independent validations with else if. A failed address check can prevent the age check from running, even though both errors need reporting. The code still looks orderly, but it answers the wrong question.

Ask whether branches compete for one result or represent separate facts. One result points to else if; separate facts point to separate if statements.

Common Else If Mistakes

The first mistake happens before the program runs: elseif and elif are not JavaScript syntax. The valid spelling is else if.

Braces cause the subtler mistakes. JavaScript permits a single unbraced statement after if or else, but an else attaches to the nearest eligible if. Indentation does not change that rule:

const accountActive = true;
const emailVerified = false;

if (accountActive)
  if (emailVerified)
    console.log("open dashboard");
  else
    console.log("verify email");
verify email

The else belongs to if (emailVerified), not if (accountActive). Braces make that ownership visible:

Which if owns else?if (accountActive)if (emailVerified)verifiedopen dashboardelseverify emailBoth outcomes sit inside the inner condition
Without braces, else attaches to the nearest eligible if—the inner email check.
const accountActive = true;
const emailVerified = false;

if (accountActive) {
  if (emailVerified) {
    console.log("open dashboard");
  } else {
    console.log("verify email");
  }
}
verify email

The output stays the same, but the structure no longer depends on indentation. Prefer braces in every branch. Code structure covers blocks and statement boundaries in more detail.

An assignment inside a condition is another quiet bug:

let status = "draft";

if (status = "published") {
  console.log(status);
}
published

status = "published" assigns a nonempty string, and that string is truthy. Use status === "published" when you mean comparison.

assignment =comparison ===stored statusdraftwrite publishedstatus changed topublishedtruthy stringstored statusdraftdraft ===published?status remainsdraftfalse result
One equals sign writes a value; three equals signs only ask a question.

Other failures come from the conditions themselves. A broad branch can make a narrower one unreachable, adjacent ranges can leave a boundary uncovered, and duplicated conditions can leave the later branch permanently unused.

Test inputs at every boundary and on both sides of it. This compact table checks the score chain:

Probe both sides of every seamretry0–59pass60–74merit75–89distinction90–100596074758990No gaps: each seam hands off to the next category
Paired tests on each seam reveal gaps and off-by-one errors.
Input>= 90>= 75>= 60Expected branchBoundary being checked
59falsefalsefalseretryimmediately below pass
60falsefalsetruepasspass begins
74falsefalsetruepassimmediately below merit
75falsetruetruemeritmerit begins
89falsetruetruemeritimmediately below distinction
90truetruetruedistinctiondistinction begins

If 90 returns "pass", ordering is wrong. If 75 returns no label, a boundary has a gap. If no input reaches "distinction", that branch is unreachable.

For a long chain, first name complicated predicates, then extract the decision into a function and test its boundaries. If the chain maps exact values, switch may fit. If it expresses ranges, an ordered else if chain often remains the clearest shape. The Coding style guide takes the same clarity-first approach across larger functions.

When to Use Switch, a Ternary, or Early Returns

else if is one of several selection tools, but the alternatives solve different shapes of problem.

Use switch when one expression is repeatedly compared with exact values:

function describeStatus(status) {
  switch (status) {
    case "draft":
      return "still being edited";
    case "review":
      return "waiting for review";
    case "published":
      return "visible to readers";
    default:
      return "unknown status";
  }
}

console.log(describeStatus("review"));
waiting for review

A switch starts at the first case whose expression is strictly equal to its input. Without a break, return, or another control transfer, execution continues into later clauses. Returning from every branch avoids that fallthrough here. JavaScript Switch Statement: A Visual Guide covers that behavior with larger examples.

Use the conditional operator, often called a ternary, for one concise value choice:

const score = 64;
const result = score >= 60 ? "pass" : "retry";

console.log(result);
pass

The condition selects one of two expressions. A nested ternary can represent more branches, but an else if chain gives each condition and result their own visible block.

Use early returns for guard clauses that reject invalid or exceptional inputs before the main work:

function classifyScore(score) {
  if (!Number.isFinite(score)) {
    return "invalid score";
  }

  if (score < 0 || score > 100) {
    return "score out of range";
  }

  if (score >= 90) {
    return "distinction";
  }

  if (score >= 75) {
    return "merit";
  }

  if (score >= 60) {
    return "pass";
  }

  return "retry";
}

console.log(classifyScore(NaN));
console.log(classifyScore(105));
console.log(classifyScore(82));
invalid score
score out of range
merit

These standalone if statements still select one result because every matching branch returns from the function. The early checks remove invalid inputs, then the ordered thresholds classify the valid score.

Keep else if when you have ordered predicates or overlapping ranges and need one winning branch. Use switch for repeated exact-value cases, a ternary for one small value choice, and early returns when guard clauses make the main path easier to follow.

These choices appear throughout JavaScript Fundamentals, where conditionals sit beside the comparison, function, and control-flow rules they depend on.

Frequently asked questions

How do you write else if in JavaScript?
Write else if as two words, followed by a condition in parentheses and a block in braces. JavaScript has no elseif or elif keyword.
How does an else if chain work in JavaScript?
JavaScript tests conditions from top to bottom. The first truthy condition selects its branch, and every remaining branch in that chain is skipped.
Can more than one else if branch run?
No. An else if chain selects at most one branch because testing stops after the first match. Use separate if statements when several actions may need to run.
Does an if condition have to equal true?
No. JavaScript converts the condition to a Boolean before choosing a branch. Values such as nonempty strings, arrays, and objects are truthy even when they are not the literal value true.
When should I replace else if with switch?
Use switch when one expression is repeatedly compared with exact case values. Keep else if for ordered predicates, ranges, or conditions that test different expressions.