← JavaScript Learning Path

JAVASCRIPT V2 · FOUNDATIONS · 37

Operators、Boolean、Conditions:把中文規則變成可驗證的 Branch

上一課建立了 value、binding 與 type。現在要讓程式「依規則做不同事情」。真正的能力不是背 if 大括號,而是把規則拆成 expression、得到 Boolean、處理邊界,並用 test cases 證明 branch ordering 沒寫錯。

Learning outcomes

1. Why now:資料有了,還需要「規則」

Grade Tracker 已經知道 score = 85。但「85 是不是及格」不是資料本身,而是一條規則。

const passed = score >= 60;
score = 85→score >= 60→true→選擇 branch

程式不理解「及格」這個自然語言概念;你必須把它轉成可 evaluate 的 expression。

2. Expression 與 Operator:先得到一個 value

2 + 3           // 5
10 % 3          // 1
score >= 60     // true / false
role === "admin" // true / false
類型常見 operator結果
Arithmetic+ - * / %通常是 number
Comparison> >= < <=Boolean
Equality=== !==Boolean
Logical&& || !依 operands 產生條件結果

先問「expression 的 value 是什麼」,再問 if 會走哪裡。

3. Strict equality:先避免不必要的 coercion

5 === 5      // true
"5" === 5    // false
5 !== 6      // true

本站基礎課預設使用 === / !==。這可以讓你在比較時同時尊重 value 與 type,而不是把 coercion 隱藏在 equality 裡。

const raw = "60";

console.log(raw === 60);         // false
console.log(Number(raw) === 60); // true

這正好接回上一課:資料 boundary 的 type contract 會直接影響規則結果。

4. Boolean operators:AND、OR、NOT 是規則組合器

const canEdit =
  loggedIn && isOwner;

const canView =
  isPublic || isOwner;

const enabled =
  !disabled;
Operator讀法典型用途
&&兩邊都成立登入且擁有資源
||至少一邊成立公開或擁有資源
!反轉條件不是 disabled

複雜規則先拆成有名字的 Boolean,通常比一口氣塞進巨大 if 更容易 debug。

5. Worked Example A:if / else 只做 branch selection

const score = 59;

if (score >= 60) {
  console.log("Pass");
} else {
  console.log("Fail");
}
Step 1讀取 score → 59
Step 2evaluate 59 >= 60 → false
Step 3跳過 true branch
Step 4執行 else → "Fail"

最重要的是 Step 2。很多 logic bug 其實發生在 condition,不在大括號。

6. Worked Example B:else if 的順序就是 business rule

function gradeLabel(score) {
  if (score >= 90) return "A";
  if (score >= 80) return "B";
  if (score >= 60) return "Pass";
  return "Fail";
}

score = 95 時,第一個 condition 就成立,function 直接 return "A"。

如果把順序寫成:

if (score >= 60) return "Pass";
if (score >= 90) return "A";

95 會先符合 >= 60,第二條永遠沒有機會處理它。程式語法完全合法,但 business result 錯了。

7. Boundary cases:邊界比「隨便試一個值」更有資訊

規則是 score >= 60,最有價值的測資不是 80,而是:

59 → Fail
60 → Pass
61 → Pass

因為這三個值直接驗證 operator 是否用了正確的 >=。同理,年齡、費率、折扣、日期區間都應先找 boundary。

8. Truthy / Falsy:條件位置不只接受 Boolean literal

if ("hello") console.log("runs");
if (1) console.log("runs");

if ("") console.log("does not run");
if (0) console.log("does not run");
if (null) console.log("does not run");
if (undefined) console.log("does not run");

JavaScript 會在 condition context 進行 Boolean coercion。這很常見,但初學者最容易把「有字串內容」和「字串看起來寫著 false」混為一談:

Boolean("false") // true

因為它是非空字串。重要規則建議寫得明確,不要讓 domain logic 全靠 truthy/falsy 猜。

9. Worked Example C:票價分類要先寫範圍,再寫 code

規則:

function fareCategory(age) {
  if (age <= 5) return "child";
  if (age <= 17) return "youth";
  if (age <= 64) return "adult";
  return "senior";
}

因為前面的 branch 已排除較小範圍,後面不必重複寫 age >= 6。但這種簡化只有在 ordering 清楚時才安全。

10. Common mistakes

A. 邊界 operator 寫錯

if (score > 60) // 60 被錯誤排除

B. branch 順序太寬

if (score >= 60) return "Pass";
if (score >= 90) return "A";

C. type 沒 normalize

const raw = "60";
raw === 60 // false

D. 把 assignment 與 comparison 混在一起

看到 condition 結果怪異時,先重新讀 expression 的目的:你是要「比較」,還是要「重新指定 state」?

11. Debug evidence:建立 decision table

條件錯誤最有效的方法之一,是把 input 與 expected branch 寫成表:

age 5  → child
age 6  → youth
age 17 → youth
age 18 → adult
age 64 → adult
age 65 → senior

然後實際印出:

console.log({
  age,
  category: fareCategory(age)
});

你正在驗證的是 rule contract,不是「看起來差不多」。

12. Guided exercise:追蹤複合條件

const loggedIn = true;
const isOwner = false;
const isAdmin = true;

const canDelete =
  loggedIn && (isOwner || isAdmin);
  1. 先算括號 isOwner || isAdmin。
  2. 再和 loggedIn 做 AND。
  3. 寫出每一步 Boolean value。

13. Independent exercise:實作 fareCategory(age)

不用複製上面的答案。自己從規則表重寫一次,並測 5、6、17、18、64、65。再故意把一個 operator 改錯,看哪個 boundary test 會先紅。

14. Challenge:把 validation 與分類分開

思考 age = -5 或 age = 200。分類 function 應該直接接受嗎?這會帶出下一層設計:

raw input
→ normalize
→ validate
→ classify

現在先不用做完整 validation framework;但要開始分辨「資料是否合法」與「合法資料屬於哪個 branch」是兩個問題。

Project checkpoint:Grade Tracker 的可測試規則

function isPassed(score) {
  return score >= 60;
}

function gradeLabel(score) {
  if (score >= 90) return "A";
  if (score >= 80) return "B";
  if (score >= 60) return "Pass";
  return "Fail";
}

專案現在從單純保存資料,進化成「資料 + 可驗證規則」。下一課會把同一套規則套到多筆資料。

15. Vocabulary / Summary

16. Further reading

Knowledge check

  1. 解釋 "60" === 60 為什麼是 false。
  2. 把「登入且(owner 或 admin)」寫成 Boolean expression。
  3. 說明為什麼 59/60/61 比只測 80 更能驗證及格規則。
  4. 指出錯誤 branch ordering 如何讓高分永遠到不了 A。
  5. 完成頁面下方 mastery exercise,讓所有 boundary tests PASS。