JavaScript Boolean Logic and Selection
In this module we explore the core concepts of Boolean expressions, if statements, nested conditionals, the infamous dangling else problem, and switch statements. Mastery of these topics is…

What will be logged by the following code? let mark = 90; if ( mark >= 80 ) { grade = 'A'; } console.log( 'Your grade is ' + grade );
Why does adding a semicolon after an if condition cause a logic error? if ( mark >= 80 ); { grade = 'A'; }
For the nested if chain grading scores, what grade is assigned when score = 70?
What is the output of the following code? let i = 1, j = 2, k = 3; if (i > j) if (i > k) console.log("A"); else console.log("B");
Which version of the salaryIncrement function correctly returns 200 for a salary of 1500?
In the switch example, why does the output remain "Welcome to SP" even when txt is changed to "PP"?
What value does y have after this switch executes? let x = 3, y = 3; switch (x + 3) { case 6 : y = 1; default: y += 1; }
Which of the following correctly simplifies the salaryIncrement function while preserving behavior?
When using logical operators, what is the result of !false && true?
Which statement best describes the effect of omitting braces in a single‑statement if‑else?
Understanding JavaScript Boolean Logic and Selection Statements
In this module we explore the core concepts of Boolean expressions, if statements, nested conditionals, the infamous dangling else problem, and switch statements. Mastery of these topics is essential for writing correct, readable, and maintainable JavaScript code.
1. Boolean Operators: && vs ||
JavaScript uses the logical AND (&&) and OR (||) operators to combine multiple Boolean expressions. The && operator returns true only when both operands are true, while || returns true when any operand is true.
Consider the following quiz question:
- Given
num = 8, which expression correctly checks ifnumis divisible by both 2 and 3?
The correct answer is:
(num % 2 == 0) && (num % 3 == 0)
Explanation:
- The modulo operator (
%) yields the remainder after division. If the remainder is0, the number is divisible by the divisor. - Both conditions must be true, so we combine them with
&&. Using||would incorrectly accept numbers divisible by only one of the divisors.
2. Simple if Statements and Variable Scope
When an if block assigns a value to a variable, that variable must exist in the appropriate scope. JavaScript’s let and var declarations are block‑scoped and function‑scoped respectively.
Quiz example:
let mark = 90;
if ( mark >= 80 ) { grade = 'A'; }
console.log( 'Your grade is ' + grade );
The output is Your grade is A. Even though grade was not declared with let inside the block, JavaScript creates a global variable when an assignment occurs without a prior declaration (in non‑strict mode). In strict mode this would throw a ReferenceError, so it’s best practice to always declare your variables.
3. The Semicolon Pitfall After if
Placing a semicolon directly after the condition of an if statement terminates the conditional, turning the following block into an independent statement that always executes.
if ( mark >= 80 ); { grade = 'A'; }
Why is this a logic error?
- The semicolon ends the
ifstatement, so the block{ grade = 'A'; }runs regardless of the condition. - Consequently, the program behaves as if the condition were always true, potentially overwriting values unintentionally.
Always write if (condition) { … } without a trailing semicolon.
4. Nested if Chains for Grading Logic
When multiple exclusive ranges need to be evaluated, a series of else if statements is clearer than deeply nested if blocks.
Example grading logic:
let score = 70;
let grade;
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else if (score >= 70) {
grade = 'C';
} else if (score >= 60) {
grade = 'D';
} else {
grade = 'F';
}
When score = 70, the condition score >= 70 is true, so the grade assigned is C. This demonstrates the importance of ordering conditions from highest to lowest.
5. The “Dangling Else” Problem
JavaScript follows the rule that an else is paired with the nearest preceding unmatched if. This can lead to unexpected behavior when braces are omitted.
let i = 1, j = 2, k = 3;
if (i > j) if (i > k) console.log("A"); else console.log("B");
Because i > j is false, the outer if body is skipped entirely, and the inner else is never reached. Therefore nothing is printed. Adding explicit braces removes ambiguity:
if (i > j) {
if (i > k) {
console.log("A");
} else {
console.log("B");
}
}
6. Writing Correct Functions: The Salary Increment Example
When a function must return a specific value based on input ranges, ensure the conditional logic covers all cases and uses the correct comparison operators.
Correct implementation:
function salaryIncrement(salary) {
let increment = 0;
if (salary >= 2000) {
increment = 300;
} else if (salary < 1000) {
increment = 100;
} else {
increment = 200;
}
return increment;
}
For a salary of 1500, the function returns 200 because it falls into the final else block.
7. Switch Statements and Fall‑Through
The switch statement evaluates an expression and executes the matching case block. If a break is omitted, execution falls through to subsequent cases.
Consider this scenario:
let txt = "PP";
if (txt === "SP") {
console.log("Welcome to SP");
} else {
switch (txt) {
case "PP":
console.log("Welcome to PP");
break;
default:
console.log("Welcome to SP");
}
}
The output remains "Welcome to SP" because the if condition is evaluated first. Since txt is not "SP", the else block runs, but the switch contains a default that also prints the same message. Understanding the flow of if…else before a switch prevents logical duplication.
8. Switch with Implicit Fall‑Through
When a case lacks a break, execution continues into the next case or the default. This can be used intentionally, but often leads to bugs.
let x = 3, y = 3;
switch (x + 3) {
case 6:
y = 1;
default:
y += 1;
}
Here x + 3 evaluates to 6, matching case 6. Because there is no break, the code falls through to the default block, incrementing y again. Starting with y = 3, the first assignment sets y = 1, then y += 1 makes it 2. Thus the final value of y is 2.
9. Best Practices for Conditional Logic
- Always use braces for
if,else, andcaseblocks to avoid accidental fall‑through. - Prefer
===over==to prevent type‑coercion surprises. - Declare variables with
letorconstbefore using them. - Order
else ifchains from most restrictive to least restrictive conditions. - When using
switch, includebreakunless intentional fall‑through is required, and place thedefaultcase at the end.
10. Quick Quiz Recap
Test your understanding with the following condensed questions:
- Which operator checks that
numis divisible by both 2 and 3? Answer:(num % 2 == 0) && (num % 3 == 0) - What is printed after assigning
grade = 'A'whenmark = 90? Answer:Your grade is A - Why does a trailing semicolon after
ifcause the block to always run? Answer: The semicolon ends theif, making the block independent. - When
score = 70, which grade is chosen in a properelse ifchain? Answer:C - What does the dangling
elseexample output? Answer: Nothing is printed. - Which version of
salaryIncrementreturns 200 for a salary of 1500? Answer: The version with proper range checks and a finalelseassigning 200. - Why does the switch example still log "Welcome to SP" when
txt = "PP"? Answer: The precedingifblock controls the output, and thedefaultrepeats the same message. - What final value does
yhave after the switch with fall‑through? Answer:2
By mastering these patterns, you will write more reliable JavaScript code and avoid common logical pitfalls.
