3.1 Module 3 · Decisions & Loops

Logical & Comparison Operators

Learn how to compare values and combine conditions to produce true or false — the foundation of every decision your code will ever make.

1

Definition

Comparison operators compare two values and return a boolean — e.g. is a greater than b? Are they equal? Logical operators combine multiple boolean expressions — e.g. is condition A and condition B both true?

Together they power every if statement, loop condition, and decision in JavaScript. Understanding the difference between == and === in particular is one of the most important fundamentals in the language.

2

Simple Way

Think of these operators as questions JavaScript asks before deciding what to do next:

=== "Are these exactly equal — same value and same type?"
> / < "Is one bigger or smaller than the other?"
&& "Are both conditions true? (AND)"
|| "Is at least one condition true? (OR)"
! "Flip the result — NOT true becomes false, and vice versa"
3

Code Examples

Example 1 — Comparison Operators
let a = 10;
let b = "10";

console.log(a == b);   // true  — same value, type ignored
console.log(a === b);  // false — different types (number vs string)
console.log(a != b);   // false — values are equal
console.log(a !== b);  // true  — types are different

console.log(10 > 5);   // true
console.log(10 < 5);   // false
console.log(10 >= 10); // true
console.log(10 <= 9);  // false
Output
Click ▶ Run to execute
Explanation
  • == checks only value — it converts types before comparing (loose equality)
  • === checks value and type — no conversion (strict equality, always prefer this)
  • !== is the strict "not equal" — returns true when value or type differs
Example 2 — Logical Operators (&&, ||, !)
let age   = 20;
let hasID = true;

// && (AND) — both must be true
console.log(age > 18 && hasID);   // true  (both true)
console.log(age > 18 && !hasID);  // false (second is false)

// || (OR) — at least one must be true
console.log(age < 18 || hasID);   // true  (second is true)
console.log(age < 18 || false);   // false (both false)

// ! (NOT) — flips the boolean
console.log(!hasID);              // false
console.log(!false);              // true
Output
Click ▶ Run to execute
Explanation
  • && (AND) — the result is true only when every condition is true
  • || (OR) — the result is true when at least one condition is true
  • ! (NOT) — inverts the boolean: !true === false, !false === true
Example 3 — Short-Circuit Evaluation
// && stops as soon as it finds false
console.log(false && console.log("A")); // "A" never prints!

// || stops as soon as it finds true
console.log(true || console.log("B"));  // "B" never prints!

// Practical use: default values
let userName = null;
let displayName = userName || "Guest"; // if userName is falsy, use "Guest"
console.log(displayName);
Output
Click ▶ Run — notice what does NOT print!
Explanation
  • Short-circuit means JavaScript stops evaluating as soon as the result is determined
  • false && anything — the right side is never reached because the result is already false
  • true || anything — the right side is never reached because the result is already true
  • The || default value pattern is widely used to provide fallbacks
Example 4 — Combining Multiple Conditions
let score    = 75;
let attended = true;

// Pass if score >= 60 AND attended
let passed = score >= 60 && attended;
console.log("Passed:", passed);

// Grade logic
let isA = score >= 90;
let isB = score >= 75 && score < 90;
let isC = score >= 60 && score < 75;

console.log("A grade:", isA);
console.log("B grade:", isB);
console.log("C grade:", isC);
Output
Click ▶ Run to execute
Explanation
  • Multiple comparison operators can be combined with logical operators to express complex rules
  • Each condition evaluates to a boolean — the logical operator then combines them
  • Use parentheses to make grouping explicit when combining && and ||
4

Real-Life Example

Think of a club's entry check — every rule maps directly to an operator:

===
ID name must exactly match the booking — value AND type must be the same
> / <
Age must be over 18 — a numeric comparison
&&
Must be over 18 AND have a valid ID — both conditions required
||
VIP pass OR special permission — either one is enough to enter
!
If you do NOT have ID — the bouncer flips the check to denied
!==
Guest name does NOT match the list — strict mismatch check
5

HTML + JavaScript Example

Click ▶ Preview, enter your age and check the ID box, then click Check — watch && and || decide the outcome in real time.

Live in Browser — Eligibility Checker
<!DOCTYPE html>
<html>
<head><title>Operators Demo</title></head>
<body style="font-family:sans-serif;padding:24px;background:#f8f9fa">

  <h2>Check Eligibility</h2>

  <label>Age:
    <input id="ageInput" type="number" placeholder="Enter age"
      style="padding:6px 10px;border:1px solid #ccc;border-radius:6px;
             font-size:1rem;width:130px;margin-left:8px">
  </label><br><br>

  <label style="display:flex;align-items:center;gap:8px;cursor:pointer">
    <input id="idCheck" type="checkbox"
      style="width:16px;height:16px;cursor:pointer">
    Has valid ID
  </label><br>

  <button onclick="checkEligibility()"
    style="padding:8px 18px;background:#f7df1e;border:none;border-radius:6px;
           cursor:pointer;font-weight:700;font-size:1rem">
    Check
  </button>
  <div id="output" style="margin-top:16px;line-height:2.2;font-size:0.95rem"></div>

  <script>
    function checkEligibility() {
      let age   = Number(document.getElementById("ageInput").value);
      let hasID = document.getElementById("idCheck").checked;

      if (!age) {
        document.getElementById("output").innerHTML =
          "<b style='color:red'>Please enter an age.</b>";
        return;
      }

      let isAdult    = age >= 18;
      let canEnter   = isAdult && hasID;
      let partialPass = isAdult || hasID;

      document.getElementById("output").innerHTML =
        "<b>Age (>= 18):</b> " + isAdult + "<br>" +
        "<b>Has ID:</b> " + hasID + "<br>" +
        "<b>Can enter (age AND id):</b> <b style='color:" +
          (canEnter ? "green" : "red") + "'>" + canEnter + "</b><br>" +
        "<b>Partial pass (age OR id):</b> " + partialPass;
    }
  </script>

</body>
</html>
Live Preview
6

Tasks (Practice)

Easy Task 1 — Greater or smaller check
Starter code
let num = 60;

// Print true or false — is num greater than 50?
console.log(num > 50);
  • Run the code — confirm it prints true
  • Change num to 40 and run again — confirm it prints false
  • Add a check using === to see if num equals 50 exactly
Medium Task 2 — Login validator
Starter code
let username = "admin";
let password = "1234";

// Use && to check both conditions at once
  • Use === and && to check if both username and password are correct
  • Store the result in a let isLoggedIn variable and print it
  • Try changing either value and confirm the result switches to false
7

MCQs

Q1
What will be the output?
console.log(5 == "5");
Output
Run it to verify
  • A false
  • B true
  • C Error
  • D undefined
💡 B is correct. == performs type coercion — the string "5" is converted to the number 5 before comparing, so the values match and the result is true. This is why === is preferred.
Q2
What will be the output?
console.log(5 === "5");
Output
Run it to verify
  • A true
  • B false
  • C undefined
  • D Error
💡 B is correct. === checks value and type. 5 is a number and "5" is a string — different types, so the result is false with no conversion.
Q3
What does the && operator mean?
let a = true;
let b = false;
console.log(a && b);
console.log(a || b);
Output
Run it to verify
  • A OR — at least one must be true
  • B AND — both must be true
  • C NOT — flips the value
  • D XOR — exactly one must be true
💡 B is correct. && (AND) returns true only when both operands are true. If either is false, the result is false. || (OR) returns true if at least one is true.
8

Pro Tips & Extra Knowledge

  • 01

    Always prefer === over == — loose equality causes unexpected bugs that are very hard to track down:

    == vs === traps
    console.log(0 == false);   // true  — coercion!
    console.log(0 === false);  // false — correct
    
    console.log("" == false);  // true  — coercion!
    console.log("" === false); // false — correct
    
    console.log(null == undefined);  // true  — coercion!
    console.log(null === undefined); // false — correct
    Output
    Click ▶ Run to execute
  • 02

    Use ! to toggle boolean values cleanly — a common pattern for on/off switches:

    Toggle with !
    let isActive = true;
    
    isActive = !isActive; // toggle off
    console.log(isActive); // false
    
    isActive = !isActive; // toggle on
    console.log(isActive); // true
    Output
    Click ▶ Run to execute
  • 03

    Use || for default values when a variable might be falsy — a very common real-world pattern:

    || default value pattern
    let userInput = "";          // empty string — falsy
    let name      = userInput || "Guest";
    console.log(name); // "Guest" — fallback used
    
    let score     = 0;           // zero — also falsy!
    let display   = score || "No score yet";
    console.log(display); // "No score yet" — careful with 0!
    Output
    Click ▶ Run to execute
  • 04

    Use the nullish coalescing operator (??) when you only want to fall back on null or undefined — not on 0 or empty string:

    ?? vs || for defaults
    let score = 0;
    
    console.log(score || 100);  // 100 — 0 is falsy, || replaces it
    console.log(score ?? 100);  // 0   — ?? only replaces null/undefined
    
    let empty = null;
    console.log(empty ?? "default"); // "default"
    Output
    Click ▶ Run to execute
Mini Challenge

Operator precedence matters here — evaluate step by step, then run to confirm.

What does this print?
console.log(10 > 5 && 5 < 3 || true);
Output
Think first, then run!
Step-by-Step Explanation
// Full expression: 10 > 5 && 5 < 3 || true

// Operator precedence (highest to lowest here):
//   > and <  evaluate first  (comparison)
//   &&       evaluates next  (AND)
//   ||       evaluates last  (OR)

// Step 1: evaluate comparisons
//   10 > 5  → true
//   5 < 3   → false

// Expression now: true && false || true

// Step 2: evaluate && (higher precedence than ||)
//   true && false → false

// Expression now: false || true

// Step 3: evaluate ||
//   false || true → true

// Output → true

// Key takeaway:
//   && binds tighter than || — the same way * binds before +
//   Use parentheses to make intent explicit:
//   (10 > 5 && 5 < 3) || true   → same result, much clearer