Part 1 · Lesson 3 · 18 min read
Conditions: if / else
Teach the program to make decisions. Comparisons, && and ||, else-if chains, and common questions: even or odd, largest of three, leap year.
On this page
Making decisions in code
So far every line runs, from top to bottom. Real programs also need to decide. For example: if it is raining, take an umbrella. Otherwise, do not. A condition is a question whose answer is true or false. Those two values are called booleans. The if statement runs a block (a group of lines inside curly braces) only when the condition is true.
Almost every DSA solution has decisions inside it. Examples are “is this number bigger than my best so far?”, “have I found the target?” and “is this character a vowel?”. This lesson teaches how to write them.
Comparisons give true or false
A comparison operator compares two values and gives true or false. The operators are > (greater than), < (less than), >=, <=, === (equal) and !== (not equal).
console.log(5 > 3); // trueconsole.log(5 < 3); // falseconsole.log(5 >= 5); // true (greater than OR equal)console.log(4 <= 3); // falseconsole.log(7 === 7); // true (equal: same value AND same type)console.log(7 === "7"); // false (number vs string)console.log(7 !== 8); // true (not equal)== (two equals signs) changes the type of a value before it compares. So 7 == "7" is true. This is a common cause of bugs that are hard to see. === compares the value and the type. Use === and !== every time.
if and else
const temperature = 31;if (temperature > 30) { console.log("It's hot — drink water");} else { console.log("Nice weather");}console.log("Have a good day");/* Output:It's hot — drink waterHave a good day*/- The condition goes in round brackets
( ). The code to run goes in curly braces{ }. elseis optional. Its block runs when the condition isfalse.- When there is an
else, exactly one of the two blocks runs. Never both, and never neither. - Indent the code inside the braces (move it to the right). The computer does not need this, but people who read your code, including interviewers, do.
else if — choosing one of many
When there are more than two possibilities, chain them with else if. The computer checks the conditions from the top. It runs only the first block whose condition is true, then it skips the rest of the chain.
const marks = 82;if (marks >= 90) { console.log("A");} else if (marks >= 75) { console.log("B"); // ← this one runs} else if (marks >= 50) { console.log("C"); // skipped, even though 82 >= 50 is also true} else { console.log("F");}/* Output:B*/82 is also ≥ 50, but “C” is never printed, because the chain already stopped at “B”. So check the strictest condition first (≥ 90, then ≥ 75, then ≥ 50). If you reverse the order, everyone above 50 gets a C.
&&, || and ! — combining conditions
Logical operators join or change conditions. && means AND, || means OR, and ! means NOT.
| Operator | Read it as | True when |
|---|---|---|
a && b | a AND b | both are true |
a || b | a OR b | at least one is true |
!a | NOT a | a is false |
const age = 20;const hasTicket = true;console.log(age >= 18 && hasTicket); // true both must be trueconsole.log(age < 13 || age > 60); // false at least one must be trueconsole.log(!hasTicket); // false ! flips true ↔ falseconst n = 15;if (n % 3 === 0 && n % 5 === 0) { console.log("divisible by both"); // divisible by both}The one-line if: ? :
The ternary operator is an operator with three parts. It chooses one of two values: condition ? valueIfTrue : valueIfFalse. If the condition is true, you get the first value. If not, you get the second. Use it for simple choices. For anything with more than one step, a normal if is clearer.
const n = 7;const kind = n % 2 === 0 ? "even" : "odd";console.log(kind); // oddTruthy and falsy values
A condition does not have to be a comparison. JavaScript can treat any value as true or false inside a condition. A value that counts as false is called falsy. A value that counts as true is called truthy. These six common values are falsy. Every other value is truthy. (There are two rare extra falsy values, -0 and 0n, which you will not need now.)
// These six values count as false inside a condition ("falsy"):// false, 0, "" (empty text), null, undefined, NaN// Every other value counts as true ("truthy") — including "0", "false" and [].const name = "";if (name) { console.log("Hello, " + name);} else { console.log("No name given"); // No name given}const count = 0;console.log(count ? "has items" : "empty"); // emptyif (count) is false when count is 0. Sometimes 0 is a real value in your problem, such as an index or a score. Then write the full comparison: if (count !== undefined) or if (index >= 0).
switch — matching one value against many
A switch statement compares one value against a list of exact options (a day number, a command, a menu choice). Each option is a case. It is easier to read than a long else if chain.
const day = 3;let name;switch (day) { case 1: name = "Monday"; break; case 2: name = "Tuesday"; break; case 3: name = "Wednesday"; // ← day is 3, so this case runs break; // ← break leaves the switch default: name = "Unknown"; // runs when no case matches}console.log(name); // Wednesday- JavaScript compares the value with each
caseusing===. breakends the switch. Without it, the code continues into the next case. This is called falling through.defaultruns when no case matches. It works like a finalelse.
Falling through is useful when several values share the same result:
const month = 4;let days;switch (month) { case 4: case 6: case 9: case 11: days = 30; // several cases can share one block break; case 2: days = 28; break; default: days = 31;}console.log(days); // 30Use switch for exact matches against a list of values. Use if / else if for ranges (like marks >= 90) and for conditions that combine several checks.
Traced: a grading program
Step through this program. It turns marks into a grade.
Store the input.
▶const marks = 82;2if (marks >= 90) {3 console.log("A");4} else if (marks >= 75) {5 console.log("B");6} else {7 console.log("C or below");8}9console.log("done");| marks | 82 |
Now try it in your head with marks = 95 and marks = 40. Which lines run each time?
| marks | marks >= 90? | marks >= 75? | Prints |
|---|---|---|---|
| 95 | true | (not checked) | A |
| 82 | false | true | B |
| 40 | false | false | C or below |
Four common mistakes
- One equals sign in a condition.
=assigns a value,===compares two values. This code has a serious bug:JavaScriptlet n = 5;if (n = 10) { // ✗ ONE equals sign: this SETS n to 10 console.log("ten?"); // runs, because 10 counts as true}console.log(n); // 10 — the bug changed n!/* Output:ten?10*/ - Wrong order in an else-if chain. A broad condition placed first matches values that were meant for later branches (see above).
- Chaining comparisons like maths.
1 < x < 5does not mean “x is between 1 and 5”. JavaScript first works out1 < x, which givestrueorfalse, and then compares that result with 5. Writex > 1 && x < 5instead. - Separate ifs instead of else if. With three separate
ifstatements, all three are checked, and more than one can run. Anelse ifchain runs at most one block.
Practice questions
Print even or odd for a given whole number.
Hint 1
Hint 2
%. Check whether n % 2 === 0.Show all 3 solutions with explanations
If the remainder after dividing by 2 is 0, print “even”; otherwise print “odd”.
const n = 7;if (n % 2 === 0) { console.log("even");} else { console.log("odd"); // odd}Every positive whole number leaves a remainder of either 0 or 1 when divided by 2, so exactly one branch runs. (A negative odd number such as -7 gives -1, not 1. This is why you should test === 0 and not === 1.)
Choose between the two words in one expression with condition ? a : b.
const n = 10;console.log(n % 2 === 0 ? "even" : "odd"); // evenThe ternary operator is a short if / else that gives back a value. It is best when each branch is just one value.
A number is even exactly when its last digit is 0, 2, 4, 6 or 8.
const n = 1234;const last = n % 10; // 4if (last === 0 || last === 2 || last === 4 || last === 6 || last === 8) { console.log("even"); // even} else { console.log("odd");}This is the rule you learned at school. It works, but it is longer than checking n % 2 directly.
Use Approach 1 or 2. n % 2 === 0 is the standard even-number check and appears inside many larger problems.
Print whether a number is positive, negative or zero.
Hint 1
Hint 2
n > 0, then n < 0. What is left?Show all 2 solutions with explanations
Test “greater than 0”, then “less than 0”. If neither is true, the number must be 0.
const n = -3;if (n > 0) { console.log("positive");} else if (n < 0) { console.log("negative"); // negative} else { console.log("zero");}The final else needs no condition, because zero is the only number left. Always test the edge case 0 (an unusual input at the edge of what is allowed). Interviewers will.
Math.sign(n) is a built-in function that returns 1 for positive numbers, -1 for negative numbers and 0 for zero. Then turn that result into a word.
const n = 12;const sign = Math.sign(n); // 1if (sign === 1) console.log("positive"); // positiveelse if (sign === -1) console.log("negative");else console.log("zero");The built-in function does the comparison for you. You still need a chain to turn the number into text.
Approach 1 is clearer and needs nothing special. Knowing Math.sign is useful when you only need to know if a number is positive, negative or zero.
Print the largest of three numbers.
Hint 1
a the largest? It must be at least as big as b and at least as big as c.Hint 2
a is the largest, then let b and c replace it if they are bigger.Show all 3 solutions with explanations
a is the largest if a >= b and a >= c. Otherwise check b the same way. Otherwise it is c.
const a = 4, b = 9, c = 2;if (a >= b && a >= c) { console.log(a);} else if (b >= a && b >= c) { console.log(b); // 9} else { console.log(c);}Use >=, not >. With 7, 7, 3 and a plain >, both of the first checks fail and the program wrongly prints 3.
- Start with
best = a. - If
bis bigger thanbest, replace it. - If
cis bigger thanbest, replace it.
const a = 4, b = 9, c = 2;let best = a;if (b > best) best = b;if (c > best) best = c;console.log(best); // 9| Step | Compare | best |
|---|---|---|
| start | — | 4 |
| check b | 9 > 4 → yes | 9 |
| check c | 2 > 9 → no | 9 |
JavaScript has a built-in function that returns the largest of the values you give it (these values are called its arguments).
console.log(Math.max(4, 9, 2)); // 9console.log(Math.max(7, 7, 3)); // 7This is correct and short. In an interview, mention it, but be ready to write Approach 2 by hand.
Remember Approach 2. “Keep the best so far” is the pattern that finds the largest value in a whole array (a list of values) with a loop in Lesson 8. It works for any number of values.
90 and above: A. 75–89: B. 50–74: C. Below 50: F.
Hint 1
Hint 2
else if only runs if the earlier ones failed.Show all 2 solutions with explanations
Check from the highest grade down. The first condition that is true decides the grade.
const marks = 75;if (marks >= 90) { console.log("A");} else if (marks >= 75) { console.log("B"); // B} else if (marks >= 50) { console.log("C");} else { console.log("F");}When marks >= 75 is checked, we already know marks is below 90, so it does not need to be written again. Check the boundary exactly: 75 must give B, so it is >= 75.
Write each grade as a complete range with a lower and upper limit, so the order no longer matters.
const marks = 91;if (marks >= 90) console.log("A"); // Aif (marks >= 75 && marks < 90) console.log("B");if (marks >= 50 && marks < 75) console.log("C");if (marks < 50) console.log("F");Every condition is checked, and exactly one is true. This is longer and easier to get wrong at the boundaries, so the else-if chain is better.
Use Approach 1. An else-if chain is shorter, checks fewer conditions, and cannot print two grades by mistake.
Print true if a year is a leap year, otherwise false.
Hint 1
Hint 2
year % 4 === 0. Combine the parts with || and &&.Show all 2 solutions with explanations
Translate the rule word by word into a single expression that gives true or false.
const year = 1900;const isLeap = year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);console.log(isLeap); // false| year | % 400 === 0 | % 4 === 0 | % 100 !== 0 | leap? |
|---|---|---|---|---|
| 2024 | false | true | true | true |
| 1900 | false | true | false | false |
| 2000 | true | — | — | true |
- Divisible by 400 → leap year.
- Otherwise, divisible by 100 → not a leap year.
- Otherwise, divisible by 4 → leap year.
- Otherwise → not a leap year.
const year = 2024;let isLeap;if (year % 400 === 0) isLeap = true;else if (year % 100 === 0) isLeap = false;else if (year % 4 === 0) isLeap = true;else isLeap = false;console.log(isLeap); // trueThe order is the important part. The 400 rule must come before the 100 rule, or 2000 would be wrongly rejected.
Both are correct. The chain (Approach 2) is easier to read and explain. The single expression (Approach 1) is shorter. In Approach 1, the — cells are never checked. Once the left side of || is true, JavaScript skips the right side. This is called short-circuiting.
Given three side lengths, print whether they can form a triangle.
Hint 1
Hint 2
&&.Show all 2 solutions with explanations
Write the three checks and join them with &&.
const a = 1, b = 2, c = 3;const valid = a + b > c && a + c > b && b + c > a;console.log(valid); // falseIf any one check is false, the whole expression is false.
If the longest side is shorter than the other two together, the other two checks are automatically true.
const a = 3, b = 4, c = 5;const longest = Math.max(a, b, c);const total = a + b + c;const valid = total - longest > longest; // the other two sides vs the longestconsole.log(valid); // truetotal - longest is the sum of the two shorter sides. Only this check can ever fail, so it is the only one needed.
Approach 1 follows the rule directly, so it is the safest to write in an interview. Approach 2 shows a useful habit: think about which check is the hardest to pass.
Print Fizz if n is divisible by 3, Buzz if by 5, FizzBuzz if by both, otherwise the number itself.
Hint 1
Hint 2
Show all 2 solutions with explanations
Check “both”, then “3 only”, then “5 only”, then print the number.
const n = 15;if (n % 3 === 0 && n % 5 === 0) { console.log("FizzBuzz"); // FizzBuzz} else if (n % 3 === 0) { console.log("Fizz");} else if (n % 5 === 0) { console.log("Buzz");} else { console.log(n);}Divisible by both 3 and 5 is the same as divisible by 15, so the first condition can also be written n % 15 === 0.
- Start with an empty string.
- If divisible by 3, add “Fizz”. If divisible by 5, add “Buzz”.
- If the string is still empty, print the number instead.
const n = 10;let word = "";if (n % 3 === 0) word += "Fizz";if (n % 5 === 0) word += "Buzz";console.log(word === "" ? n : word); // Buzz“FizzBuzz” appears by itself when both checks add their part. This version is easy to extend. To add a new rule (for example “Bazz” for 7), you add one more line.
Both are accepted. Approach 1 is the standard answer. Approach 2 is a good one to mention, because it shows that you think about how code may change later.
An electricity bill uses slabs (price bands). The first 100 units cost 5 each, the next 100 cost 7 each, and every unit above 200 costs 10. Print the bill for a given number of units.
Hint 1
Hint 2
Show all 2 solutions with explanations
Decide which range the units fall in. Then write the full cost for that range.
const units = 250;let bill;if (units <= 100) { bill = units * 5;} else if (units <= 200) { bill = 100 * 5 + (units - 100) * 7;} else { bill = 100 * 5 + 100 * 7 + (units - 200) * 10;}console.log(bill); // 1700| Part | Units | Rate | Cost |
|---|---|---|---|
| first slab | 100 | 5 | 500 |
| second slab | 100 | 7 | 700 |
| above 200 | 50 | 10 | 500 |
| total | 250 | 1700 |
- Units in slab 1 =
Math.min(units, 100). - Units in slab 2 = what is above 100, but at most 100.
- Units in slab 3 = whatever is above 200 (or 0).
const units = 250;const slab1 = Math.min(units, 100); // 100const slab2 = Math.min(Math.max(units - 100, 0), 100); // 100const slab3 = Math.max(units - 200, 0); // 50console.log(slab1 * 5 + slab2 * 7 + slab3 * 10); // 1700Math.max(x, 0) stops a part from going below 0. Math.min(x, 100) stops it from going above the slab size. No branches are needed, and adding a fourth slab is easy.
Approach 1 is the easiest to explain. Approach 2 does not repeat the slab prices in every branch. This matters when there are many slabs.
Given a number from 1 to 7, print the name of the day (1 is Monday). For any other number, print Invalid day.
Hint 1
Hint 2
switch (day) with one case per day, a break after each, and a default.Show all 3 solutions with explanations
One case per day number, and default for anything else.
const day = 7;let name;switch (day) { case 1: name = "Monday"; break; case 2: name = "Tuesday"; break; case 3: name = "Wednesday"; break; case 4: name = "Thursday"; break; case 5: name = "Friday"; break; case 6: name = "Saturday"; break; case 7: name = "Sunday"; break; default: name = "Invalid day";}console.log(name); // SundayEach break stops the switch after the matching case. Without the breaks, day 1 would fall through every case and end as “Invalid day”.
The same logic with if and else if.
const day = 1;let name;if (day === 1) name = "Monday";else if (day === 2) name = "Tuesday";else if (day === 3) name = "Wednesday";else if (day === 4) name = "Thursday";else if (day === 5) name = "Friday";else if (day === 6) name = "Saturday";else if (day === 7) name = "Sunday";else name = "Invalid day";console.log(name); // MondayCorrect, but every line repeats day ===. For many exact matches, switch reads better.
Store the names in order in an array (a list) and use the day number to find the right name.
const day = 9;const names = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];const name = day >= 1 && day <= 7 ? names[day - 1] : "Invalid day";console.log(name); // Invalid dayArrays (Lesson 8) number their items from 0. So day 1 is at position 0, which is why the code uses day - 1. This is the shortest version, and it is common in real code.
Use switch (Approach 1) for this lesson. Once you know arrays, the lookup (Approach 3) is usually the cleanest way to turn numbers into names.
Make it stick
- Write the leap-year rule as a single condition from memory.
- Explain why FizzBuzz must check “divisible by both” first.
- Find the bug in
if (x = 0), and say what happens tox.
Revisit schedule: solve two of the questions again tomorrow, again in 3 days, and once more in a week — without looking at the answers. Each time it will feel easier. That is the memory forming.
Next lesson is the most important one in Part 1: the for loop (code that repeats a block many times). We trace it step by step until the pattern is clear.
Practise on LeetCode
Real interview problems that use exactly what this lesson teaches. Solve them in JavaScript after the practice questions above.
Published by Jainik · Last updated · How these lessons are made
Keep learning
Related series