Course Lessons

JAVASCRIPT FOUNDATIONS + AI MINDSET

Back to Course

Conditionals: if, else, and Decisions in Code

JAVASCRIPT... Lesson 5 of 41 10 min

If-Else and Switch

Conditional Logic & Decision Making

By AI Learning Assistant  ·  JavaScript  ·  Control Flow  ·  Fundamentals

🤖 AI-POWERED LESSON

This article is paired with a live AI session. As you read, you will see real questions asked to an AI assistant and the answers that came back, showing you exactly how to use AI to master JavaScript control flow faster.

Programs need to make decisions. A script that simply runs line by line from top to bottom is rarely useful. You need the ability to check conditions, compare values, and execute different blocks of code based on what is happening at runtime. This is the domain of conditional statements.

Every application you use relies on conditional logic. When you log in, the system checks if your password matches. When you add an item to your cart, it checks if the item is in stock. When you submit a form, it validates every field. None of this happens without if statements, comparisons, and logical branching.

JavaScript gives you three primary tools for branching: if...else chains for flexible logic, switch for discrete value matching, and the ternary operator for concise binary choices. We will also cover the comparison and logical operators that power every condition, the tricky world of truthy and falsy values, and modern alternatives like lookup objects.

At each stage, we will use AI to clarify the subtle rules that separate working conditions from expert level logic.

The If Statement

THE FOUNDATION · TRUTHY CHECKS · CODE BLOCKS

The if statement evaluates a condition inside parentheses. If that condition converts to true, the code block inside the curly braces runs. If it converts to false, the block is skipped entirely. The condition does not need to be a literal boolean; JavaScript will coerce the value internally.

The coercion mechanism is both powerful and dangerous. A string containing text is truthy. An empty string is falsy. The number zero is falsy, but the string "0" is truthy. An empty array is truthy. Understanding these distinctions prevents silent bugs that can take hours to debug.

let score = 85 if ( score >= 70 ) { console . log ( "You passed!" ); }

⚠️ THE TRUTHY TRAP

JavaScript does not require the condition to be a boolean. It will coerce the value. This means if (1) runs, if (0) does not, and if ("hello") runs. Understanding which values are truthy and which are falsy is essential to avoiding silent bugs.

Else and Else If

MULTIPLE BRANCHES · EXCLUSIVE PATHS · ORDER MATTERS

When you need to choose between two paths, use else. When you have three or more possibilities, chain else if blocks. Only one block in the entire chain will ever execute. As soon as a condition is met, JavaScript runs that block and skips everything else below it.

This exclusivity is critical. If you check whether a score is passing and then separately check whether it is excellent, a score of 85 could trigger both blocks unless you structure them as an if-else-if chain. The first matching condition always wins, and the rest are ignored.

if ( score >= 70 ) { console . log ( "Pass" ); } else if ( score >= 50 ) { console . log ( "Retake" ); } else { console . log ( "Fail" );

✅ ORDER MATTERS

Conditions are evaluated from top to bottom. If you check score >= 50 before score >= 70, a score of 85 will incorrectly print "Retake" because the first matching condition wins. Always place your most specific conditions at the top.

Comparison Operators

STRICT VS LOOSE · TYPE COERCION · RELATIONAL

JavaScript offers two equality operators. === is strict equality: it checks both value and type, and never performs coercion. == is loose equality: it attempts to convert types before comparing, which leads to famously confusing results. The professional standard is to always use === and !==.

Loose equality has a complex set of rules. A number compared to a string converts the string to a number. A boolean compared to anything converts the boolean to a number first. Null and undefined are equal to each other but nothing else. These rules are so unpredictable that most style guides and linters forbid == entirely.

console . log ( 5 == "5" ); // true (coerced) console . log ( 5 === "5" ); // false (strict) // Always use === and !== in production code

🎯 RELATIONAL OPERATORS

Beyond equality, you have >, <, >=, and <= for ordering. Strings are compared lexicographically by Unicode code point, so "Z" < "a" evaluates to true because uppercase letters have lower code points than lowercase letters.

Logical Operators

AND · OR · NOT · SHORT CIRCUIT

You can combine conditions using && (AND), || (OR), and ! (NOT). && requires both sides to be truthy. || requires at least one side to be truthy. ! inverts a boolean.

Logical operators use short circuit evaluation. For &&, if the left side is falsy, the right side is never evaluated. For ||, if the left side is truthy, the right side is skipped. This behavior is exploited for default values and guard patterns.

Short circuit evaluation is not just an optimization. It is a pattern. You can use user && user.name to safely access a property only if the user exists. You can use config.timeout || 5000 to provide a default value when a setting is missing. These patterns are everywhere in professional JavaScript.

if ( isLoggedIn && isAdmin ) { console . log ( "Dashboard access granted" ); } const role = input || "guest" ; // default fallback

The Ternary Operator

CONDITION ? TRUE : FALSE · EXPRESSIONS ONLY

The conditional operator is JavaScript's only ternary operator. It takes three operands: a condition, a value if true, and a value if false. Unlike if...else, the ternary operator is an expression, meaning it returns a value and can be used inside variable assignments, template literals, and return statements.

This distinction between statements and expressions is fundamental. A statement performs an action. An expression produces a value. You cannot put a statement where JavaScript expects an expression, which is why you cannot use if...else inside a template literal but you can use a ternary.

const result = score >= 70 ? "Pass" : "Fail" ; // An expression that returns a value directly

✅ NESTING DISCIPLINE

You can nest ternaries, but you should not. A nested ternary quickly becomes unreadable. If you need more than one condition, switch to if...else or an if chain. Reserve the ternary for clean binary choices.

Switch Statements

DISCRETE VALUE MATCHING · BREAK · DEFAULT · FALL THROUGH

A switch statement evaluates an expression once, then attempts to match the result against a series of case labels using strict equality (===). When a match is found, execution begins at that case and continues through subsequent cases until a break is encountered. This behavior is called fall through.

Fall through can be useful for grouping cases. For example, you might want the same code to run for both "Saturday" and "Sunday". But forgetting break is one of the most common switch statement bugs in production code. The default case runs when no match is found, acting like the final else in an if chain.

switch ( grade ) { case 'A' : console . log ( "Excellent" ); break case 'B' : console . log ( "Good" ); break default : console . log ( "Keep trying" );

⚠️ THE FORGOTTEN BREAK

Without break, execution falls through to the next case. Sometimes this is intentional, but usually it is a bug. If you intentionally omit break, add a comment explaining why so the next developer does not accidentally insert one.

Truthy and Falsy

THE 6 FALSY VALUES · IMPLICIT COERCION · PITFALLS

In JavaScript, every value is either truthy or falsy when evaluated as a boolean. There are exactly six falsy values: false, 0, "" (empty string), null, undefined, and NaN. Everything else, including empty arrays, empty objects, and the string "0", is truthy.

This is a common source of confusion. A function that checks if (count) will skip the block when count is zero, even though zero is a perfectly valid number. To handle this, you must explicitly check for null or undefined rather than relying on truthiness when zero is a legitimate value.

console . log ( "" ? "truthy" : "falsy" ); // falsy console . log ( "0" ? "truthy" : "falsy" ); // truthy // [] and {} are also truthy

Modern Alternative: Lookup Objects

OBJECT MAPS · MAP STRUCTURES · EXTENSIBILITY

In modern JavaScript, object lookup maps and Map structures often replace switch statements entirely. Instead of a switch on status codes, you can define a plain object where keys are the cases and values are the results. This is easier to test, easier to extend, and eliminates the risk of forgotten breaks.

The Map version is even more powerful because Map keys can be any type, not just strings. You can use objects, functions, or NaN as keys. Maps also preserve insertion order and have a clean API for checking existence and iterating entries.

const statusMap = { 200 : "OK" 404 : "Not Found" }; console . log ( statusMap [ 404 ]); // "Not Found"

LIVE AI LEARNING SESSION

Ask your AI assistant this question ↓

💬 YOU ASK THE AI:

"When should I use if-else, switch, or ternary in JavaScript? What are the readability and performance differences? And when should I use a lookup object instead?"

🤖 AI RESPONDS:

This is a classic architecture question. The choice is almost never about performance; modern engines optimize all three paths similarly. The choice is about readability, maintainability, and the shape of your data.

Use Ternary for a single binary choice where you need to return or assign a value concisely. It shines inside template literals and return statements. Do not nest ternaries deeper than one level. If you find yourself writing a ternary inside a ternary, refactor to an if chain or a lookup.

Use If-Else when conditions involve ranges, logical operators, or complex boolean logic. If you need to check score >= 50 && score < 70, if-else is the only clean option. If-else is also better when different branches need to perform entirely different types of operations.

Use Switch when you are comparing one expression against many discrete, exact values. A switch is cleaner than five else if blocks checking the same variable. Remember that switch uses strict equality internally, so case "5": will not match the number 5.

Use Lookup Objects when your cases are data driven and likely to grow. An object map is easier to extend than a switch: you just add a key value pair. It is also easier to test in isolation, and you can generate it dynamically from an API response or database query.

A hidden tip: For complex state machines, consider the Strategy pattern. Instead of a giant switch, define a set of strategy functions and select the right one based on a key. This keeps each behavior in its own function and makes unit testing trivial.

Apply it: rewrite an if chain as a switch

// Before: messy if chain // After: clean switch switch ( day ) { case 1 : plan = "Monday study" ; break default : plan = "Rest"

📝 MY NOTE — IN MY OWN WORDS

The AI made the decision tree click for me. I now picture ternary as a traffic light with only two directions, if-else as a multi lane highway with speed limits and ranges, and switch as a train station where every platform has an exact destination. The object lookup tip was a revelation. I had never thought of replacing a switch with a plain object, but it makes so much sense because adding a new case is just adding a new key value pair instead of a whole new block. I also finally understand why "0" is truthy while 0 is falsy. It is not about the digit; it is about the container. A string is an object wrapper, and any non empty string is truthy. Going forward, I will always start with strict equality, default to if-else for ranges, use switch for exact string or number matches, keep ternaries for simple assignments only, and reach for lookup objects whenever my cases are likely to grow or come from external data.

Quick Comparison

FEATURE If-Else

Complete this lesson

Mark as complete to track your progress