JavaScript Else If: Chaining Multiple Conditions
Learn how to chain multiple conditions in JavaScript using else if statements. Covers syntax, execution order, real-world patterns like grading systems, and best practices for multi-way branching.
Many real-world decisions have more than two possible outcomes. A grading system does not just say "pass" or "fail"; it assigns A, B, C, D, or F. A shipping calculator does not just have "free" or "not free"; it might have express, standard, economy, and free tiers based on order weight and total. The if else statement handles two branches. The else if chain handles three, four, ten, or as many branches as you need.
This guide teaches you the complete else if syntax, explains exactly how JavaScript evaluates chains from top to bottom, shows real-world patterns like grading systems and pricing tiers, and covers the mistakes that cause conditions to fire in the wrong order.
Else If Syntax
The else if keyword goes between the initial if and the final else:
if (condition1) {
// Runs when condition1 is true
} else if (condition2) {
// Runs when condition1 is false AND condition2 is true
} else if (condition3) {
// Runs when condition1 and condition2 are false AND condition3 is true
} else {
// Runs when ALL conditions above are false
}JavaScript evaluates conditions from top to bottom. It executes the first matching block and skips every block after it. The final else is optional and acts as a catch-all default.
const score = 85;
if (score >= 90) {
console.log("Grade: A");
} else if (score >= 80) {
console.log("Grade: B");
} else if (score >= 70) {
console.log("Grade: C");
} else if (score >= 60) {
console.log("Grade: D");
} else {
console.log("Grade: F");
}
// Output: "Grade: B" (85 >= 80 is the first true condition)How Execution Order Works
Understanding execution order is critical. JavaScript stops at the first true condition and ignores the rest:
const value = 95;
if (value >= 60) {
console.log("D or above"); // This runs! (95 >= 60 is true)
} else if (value >= 70) {
console.log("C or above"); // Skipped (never evaluated)
} else if (value >= 80) {
console.log("B or above"); // Skipped
} else if (value >= 90) {
console.log("A"); // Skipped
}
// Output: "D or above" (WRONG — condition order matters!)The example above produces the wrong grade because the least specific condition (>= 60) appears first. Since 95 is greater than 60, JavaScript matches immediately and never checks the more specific conditions. Fix this by ordering from most specific to least specific:
const value = 95;
if (value >= 90) {
console.log("A"); // ✓ Most specific first
} else if (value >= 80) {
console.log("B or above");
} else if (value >= 70) {
console.log("C or above");
} else if (value >= 60) {
console.log("D or above");
} else {
console.log("F");
}
// Output: "A" (correct!)| Condition Order | Input: 95 | Input: 75 | Input: 45 |
|---|---|---|---|
Most specific first (>= 90, >= 80, ...) | A (correct) | C (correct) | F (correct) |
Least specific first (>= 60, >= 70, ...) | D (wrong) | D (wrong) | F (correct only by coincidence) |
Always Order from Most Specific to Least Specific
When using range-based conditions (greater than, less than), place the most restrictive condition first. JavaScript matches the first true condition and skips the rest. Putting a broad condition first causes it to catch values meant for more specific branches below it.
Real-World Else If Patterns
HTTP Status Code Handler
function handleResponse(statusCode) {
if (statusCode >= 200 && statusCode < 300) {
return { type: "success", message: "Request completed successfully" };
} else if (statusCode === 301 || statusCode === 302) {
return { type: "redirect", message: "Resource has moved" };
} else if (statusCode === 400) {
return { type: "client-error", message: "Bad request: check your input" };
} else if (statusCode === 401) {
return { type: "auth-error", message: "Authentication required" };
} else if (statusCode === 403) {
return { type: "auth-error", message: "Access forbidden" };
} else if (statusCode === 404) {
return { type: "not-found", message: "Resource not found" };
} else if (statusCode >= 500) {
return { type: "server-error", message: "Server error: try again later" };
} else {
return { type: "unknown", message: `Unexpected status: ${statusCode}` };
}
}
console.log(handleResponse(200)); // { type: "success", ... }
console.log(handleResponse(404)); // { type: "not-found", ... }
console.log(handleResponse(503)); // { type: "server-error", ... }Dynamic Pricing Tiers
function calculateShippingCost(weight, distance, isMember) {
let baseCost;
if (weight <= 1) {
baseCost = 5.99;
} else if (weight <= 5) {
baseCost = 9.99;
} else if (weight <= 20) {
baseCost = 14.99;
} else if (weight <= 50) {
baseCost = 29.99;
} else {
baseCost = 49.99;
}
// Distance multiplier
let multiplier;
if (distance < 100) {
multiplier = 1.0;
} else if (distance < 500) {
multiplier = 1.5;
} else if (distance < 1000) {
multiplier = 2.0;
} else {
multiplier = 3.0;
}
const total = baseCost * multiplier;
return isMember ? total * 0.85 : total; // 15% member discount
}
console.log(calculateShippingCost(3, 250, false)); // 14.985
console.log(calculateShippingCost(3, 250, true)); // 12.73725
console.log(calculateShippingCost(60, 1200, false)); // 149.97User Permissions System
function getPermissions(role) {
if (role === "superadmin") {
return {
canRead: true, canWrite: true, canDelete: true,
canManageUsers: true, canViewLogs: true,
};
} else if (role === "admin") {
return {
canRead: true, canWrite: true, canDelete: true,
canManageUsers: false, canViewLogs: true,
};
} else if (role === "editor") {
return {
canRead: true, canWrite: true, canDelete: false,
canManageUsers: false, canViewLogs: false,
};
} else if (role === "viewer") {
return {
canRead: true, canWrite: false, canDelete: false,
canManageUsers: false, canViewLogs: false,
};
} else {
return {
canRead: false, canWrite: false, canDelete: false,
canManageUsers: false, canViewLogs: false,
};
}
}Temperature Range Classifier
function classifyTemperature(celsius) {
if (celsius < -20) {
return { label: "Extreme cold", color: "#1a237e", warning: "Stay indoors" };
} else if (celsius < 0) {
return { label: "Freezing", color: "#283593", warning: "Icy roads possible" };
} else if (celsius < 10) {
return { label: "Cold", color: "#1565c0", warning: "Wear warm layers" };
} else if (celsius < 20) {
return { label: "Cool", color: "#2e7d32", warning: null };
} else if (celsius < 30) {
return { label: "Warm", color: "#f57f17", warning: null };
} else if (celsius < 40) {
return { label: "Hot", color: "#e65100", warning: "Stay hydrated" };
} else {
return { label: "Extreme heat", color: "#b71c1c", warning: "Heat advisory" };
}
}
console.log(classifyTemperature(22)); // { label: "Warm", color: "#f57f17", warning: null }
console.log(classifyTemperature(-5)); // { label: "Freezing", color: "#283593", ... }Else If with Complex Conditions
Each else if can use comparison and logical operators for multi-part conditions:
function categorizeUser(user) {
if (user.isPremium && user.purchaseCount > 50) {
return "VIP";
} else if (user.isPremium && user.purchaseCount > 10) {
return "Premium Active";
} else if (user.isPremium) {
return "Premium New";
} else if (user.purchaseCount > 20) {
return "Loyal Free";
} else if (user.purchaseCount > 0) {
return "Free Active";
} else {
return "Free Inactive";
}
}For readability, extract complex conditions into named booleans:
function categorizeUser(user) {
const isVip = user.isPremium && user.purchaseCount > 50;
const isPremiumActive = user.isPremium && user.purchaseCount > 10;
const isPremiumNew = user.isPremium;
const isLoyalFree = user.purchaseCount > 20;
const isFreeActive = user.purchaseCount > 0;
if (isVip) return "VIP";
if (isPremiumActive) return "Premium Active";
if (isPremiumNew) return "Premium New";
if (isLoyalFree) return "Loyal Free";
if (isFreeActive) return "Free Active";
return "Free Inactive";
}When to Use Else If vs Switch
| Criteria | Else If Chain | Switch Statement |
|---|---|---|
| Best for | Range checks (>, <, >=, <=) | Exact value matching (===) |
| Complex conditions | Fully supported (&&, ||, function calls) | Limited (each case is a single value) |
| Readability for 3-5 branches | Good | Good |
| Readability for 8+ branches | Gets long | Cleaner with many exact matches |
| Fall-through behavior | Not possible | Possible (can be useful or dangerous) |
// Else if: better for ranges
if (score >= 90) { grade = "A"; }
else if (score >= 80) { grade = "B"; }
else if (score >= 70) { grade = "C"; }
// Switch: better for exact values
switch (day) {
case "Monday": schedule = "Team standup"; break;
case "Wednesday": schedule = "Sprint review"; break;
case "Friday": schedule = "Retrospective"; break;
default: schedule = "Normal workday";
}Rule of Thumb
Use else if when conditions involve comparisons, ranges, or complex boolean logic. Use switch when you are matching one variable against a list of exact values. When in doubt, else if is always safe; it can express everything a switch can and more.
Best Practices
Clean Else If Chains
Follow these habits to write else if chains that are easy to read and debug.
Order conditions from most specific to least specific. For range-based conditions, the strictest condition goes first. For probability-based conditions, the most likely case goes first (for readability and minor performance benefit).
Keep chains short. If your else if chain has more than 6-7 branches, consider refactoring. Use a lookup object, a switch statement, or extract the logic into a mapping function.
Always include a final else. Even if you think all cases are covered, add an else block that handles unexpected values. This catches bugs during development and prevents silent failures in production.
Use early returns in functions. Instead of chaining else if with variable assignments, return directly from each branch. Early returns are cleaner and eliminate the need for a let variable at the top.
Avoid overlapping conditions. Each branch should cover a mutually exclusive range. If condition1 and condition2 can both be true for the same input, only the first one runs, which might not be the one you intended.
Common Mistakes and How to Avoid Them
Else If Pitfalls
These ordering and logic mistakes cause conditions to match unexpectedly.
Putting broad conditions before specific ones. if (x > 0) catches everything that if (x > 100) would catch. If the broad condition appears first, the specific condition never gets a chance to match. Always put the most restrictive condition first.
Missing the final else block. Without a default case, inputs that do not match any condition fall through silently. Add else { throw new Error("Unexpected value"); } or return a sensible default.
Duplicating conditions across branches. If two else if branches have the same condition, the second one is dead code that never executes. Review your chain for duplicate or overlapping conditions.
Using else if when all branches assign the same variable. When every branch assigns a value to the same variable, consider a ternary chain or a lookup object instead of a long else if chain.
Forgetting that only one branch executes. Unlike a series of independent if statements, else if chains are mutually exclusive. If you need multiple conditions to potentially run, use separate if statements without else.
Next Steps
Learn the switch statement
For exact value matching against many cases, the switch statement offers a structured and readable alternative.
Explore the [ternary operator](/tutorials/programming-languages/javascript/javascript-ternary-operator-complete-syntax-guide)
When an else if chain simply assigns different values to the same variable, chained ternaries can express the same logic more compactly.
Combine conditionals with loops
Use if/else if inside for and while loops to process collections with conditional logic, like filtering arrays or categorizing data.
Build a CLI tool with multi-branch logic
Create a command-line calculator or quiz app that uses else if chains to handle user input, validate commands, and provide different responses.
Rune AI
Key Insights
- First match wins: JavaScript evaluates conditions top-to-bottom and executes only the first true branch
- Order matters: place the most specific or restrictive condition first to prevent broad conditions from catching values meant for narrower ones
- Always add a default else: the final else block catches unexpected inputs and prevents silent failures
- Refactor long chains: more than 6-7 branches signals that a switch, lookup object, or strategy pattern may be clearer
Frequently Asked Questions
How many else if blocks can I chain together?
Does JavaScript evaluate all conditions in an else if chain?
Can I use else if without a final else block?
What is the difference between multiple if statements and an else if chain?
Is else if one keyword or two?
Conclusion
The else if chain is the standard tool for multi-way branching in JavaScript, letting you test as many conditions as you need with exactly one branch executing per evaluation. The most important rule is condition ordering: always place the most specific or restrictive condition first, because JavaScript stops at the first match. When chains grow beyond 6-7 branches, look for alternatives like switch statements or lookup objects that express the same logic more cleanly.
More in this topic
OffscreenCanvas API in JS for UI Performance
Master the OffscreenCanvas API to offload rendering from the main thread. Covers worker-based 2D and WebGL rendering, animation loops inside workers, bitmap transfer, double buffering, chart rendering pipelines, image processing, and performance measurement strategies.
Advanced Web Workers for High Performance JS
Master Web Workers for truly parallel JavaScript execution. Covers dedicated and shared workers, structured cloning, transferable objects, SharedArrayBuffer with Atomics, worker pools, task scheduling, Comlink RPC patterns, module workers, and performance profiling strategies.
JavaScript Macros and Abstract Code Generation
Master JavaScript code generation techniques for compile-time and runtime metaprogramming. Covers AST manipulation, Babel plugin authorship, tagged template literals as macros, code generation pipelines, source-to-source transformation, compile-time evaluation, and safe eval alternatives.