白帶 · 程式思維
第 03 章

判斷與迴圈 —
電腦的決定與重複

這章結束你會看懂電腦怎麼做選擇、怎麼重複做事,並能追出一段簡單流程會走到哪個結果。

開場 · 決定與重複

你早上出門前看天空:如果下雨,就帶傘;如果沒下雨,就輕裝出門。到飲料店時,店員又照規則算優惠:如果集滿十點,就換一杯;如果今天是會員日,再打九折。這些看起來像生活直覺,其實就是程式裡的判斷。電腦不會「感覺差不多」,它只會照你寫的條件走。更重要的是,電腦最擅長把同一件事重複做一百次、一萬次,而且不喊累。本章要把這兩個能力拆開看:決定與重複。

生活全是 if:把分岔路寫清楚

判斷(condition)就是程式裡的分岔路。你可以把它想成食譜裡的備註:「如果鍋子太乾,就加一點水;否則繼續煎。」電腦看到這種句子時,不會猜你的意思,只會檢查條件是真的還是假的。是真的,就走第一條路;是假的,就走另一條路。

JavaScript 裡最常見的寫法是 ifif 後面的括號放條件,大括號放要執行的步驟。讀的時候不要急著看每個符號,先翻成人話:「如果括號裡這件事成立,就做大括號裡的事。」這個翻譯習慣非常重要,因為你之後看 AI 產出的 code,常常第一眼就是一堆 if。只要能先翻成人話,你就不會被符號嚇到。

例如票價規則可以寫成:如果年齡小於十二歲,就顯示兒童票;否則顯示一般票。這不是數學考試,而是在描述一條規則。程式的角色,是把這條規則照順序執行。你要做的第一件事,是問自己:條件檢查的是哪個盒子?結果會走去哪一邊?這和 ch02 的變數很接近,因為條件通常就是拿變數盒子裡的值來比較。

初學者常犯的錯,不是語法少打一個括號,而是規則本身沒講清楚。例如「小孩半票」聽起來很清楚,但幾歲算小孩?十二歲算不算?未滿十二歲才算,還是十二歲以下都算?這種邊界一模糊,程式就會照某個你沒注意的方式執行。會寫判斷的人,真正厲害的地方是會把分岔講到沒有灰色地帶。

把年齡放進條件,看看流程會走到哪個票種。
const age = 10;
if (age < 12) {
  console.log('兒童票');
} else {
  console.log('一般票');
}

if / else if / else:從上往下試規則

if / else if / else 是多條分岔路。可以想成飲料店集點規則:如果滿十點,換一杯;不滿十點但滿五點,加送珍珠;兩個都沒有,就照原價。電腦會從上往下檢查。第一個成立的條件被選中後,後面就不看了。

這個「從上往下,只選第一個成立」很關鍵。假設客人有十二點,滿十點也成立,滿五點也成立。如果你把「滿五點」寫在前面,電腦會先送珍珠,然後停下來,不會再往下看到「滿十點換一杯」。人類會覺得十二點當然該用最大優惠,但電腦不會替你排序。食譜怎麼寫,它就怎麼做。

else 的意思是「以上都不是」。它不需要再寫條件,因為它接住的是前面全部失敗的情況。讀 code 時,你可以把整段想成一串檢票口:第一口通過就進場;沒通過就到下一口;全部沒通過,就走最後的預設出口。這樣追流程會比盯著括號輕鬆很多。

寫給 AI 的需求也要有這個意識。不要只說「幫我做優惠判斷」,而要說清楚順序:先判斷十點以上,再判斷五點以上,最後才是無優惠。AI 是實習生,不是你肚子裡的店長。你沒有講順序,它可能寫出能跑、但商業規則錯掉的 code。

多條規則會從上往下檢查,第一個成立就結束。
const points = 12;
if (points >= 10) {
  console.log('換一杯免費飲料');
} else if (points >= 5) {
  console.log('加送珍珠');
} else {
  console.log('照原價');
}

條件怎麼寫:比較、而且、或者

條件式(expression)會算出一個真假值。最常見的是比較:> 大於、< 小於、>= 大於等於、<= 小於等於、=== 等於。注意 JavaScript 裡判斷相等常用三個等號 ===,不是一個等號。一個等號通常是把值放進變數盒子,三個等號才是在問「兩邊一樣嗎?」

生活裡很多規則不是單一條件。例如自動售票機可能規定:年齡小於十二歲,而且投幣金額至少二十元,才出票。這裡的「而且」在程式裡常寫成 &&,意思是兩邊都要成立。只要有一邊不成立,整個條件就是假。另一種是「或者」,寫成 ||,意思是只要有一邊成立就可以。像「學生或者六十五歲以上」可享優惠,就是或者。

讀條件時,請先不要急著算。先把每個小條件圈出來,再看它們中間是而且還是或者。這跟看合約很像:一個字不同,結果差很多。age < 12 || isStudent 是小孩或學生都優惠;age < 12 && isStudent 是小孩且學生才優惠。兩段看起來只差兩個符號,實際上服務的人完全不同。

AI 寫錯邏輯,常常錯在這種地方。它可能把「滿千折百」寫成 total > 1000,導致剛好一千元沒有折扣;也可能把「學生或長者」寫成「學生且長者」。你不必背所有語法,但一定要養成讀條件邊界的習慣:等於算不算?兩個條件是都要,還是任一個就好?

用或者與而且組合條件,判斷是否符合優惠。
const age = 20;
const isStudent = true;
const price = 50;
if ((age < 12 || isStudent) && price >= 50) {
  console.log('符合優惠');
} else {
  console.log('不符合優惠');
}

for 迴圈:不用把同一句話寫三十次

迴圈(loop)是重複做事的工具。如果老師要印三十張獎狀,你不會真的寫三十份食譜:「印第一張、印第二張、印第三張……」你會寫成「從第一位學生開始,每位學生印一張,直到名單結束」。程式也是一樣。重複的規則一旦抓出來,就可以交給迴圈。

for 迴圈常用在「次數明確」的情況。它通常有三件事:從哪裡開始、什麼時候繼續、每次做完怎麼往前。你可以把它讀成櫃台叫號:號碼從一開始;只要號碼小於等於三,就服務;服務完號碼加一。這樣就會服務一號、二號、三號,然後在四號時停下。

很多人第一次看到 i++ 會卡住。它只是「把 i 這個變數加一」的短寫。i 也不神秘,只是慣用的計數器名字。你也可以把它想成手上的計數牌。每跑一次迴圈,計數牌往前一格。迴圈真正要你看懂的是:它會跑幾次?每次跑的時候,計數器是多少?

追迴圈最可靠的方法,是手動畫一張小表。第一欄寫第幾次,第二欄寫計數器,第三欄寫輸出。不要在腦中硬轉,尤其初學時很容易少算一次或多算一次。工程師也常這樣做,只是熟了以後表格藏在腦中。你現在把它寫出來,是在建立同一種肌肉。

次數明確時,用 for 迴圈把重複工作交給電腦。
for (let i = 1; i <= 3; i++) {
  console.log('印第 ' + i + ' 張獎狀');
}

while 與無限迴圈:停下來的條件要寫對

while 迴圈適合「不知道會跑幾次,但知道什麼時候該停」的情況。掃地機器人就是好例子:只要電量還夠,就繼續掃;電量不足,就回充電座。它不是一開始就知道會掃幾圈,而是每次行動前都檢查條件。

while 的讀法很直覺:「當括號裡的條件還成立,就一直做大括號裡的事。」問題也出在這裡:如果條件永遠成立,程式就會一直跑,這叫無限迴圈(infinite loop)。例如電量一開始是三格,條件是電量大於零,但你忘了在迴圈裡讓電量減少。電腦就會以為永遠還有電,掃到天荒地老。

無限迴圈不是電腦壞掉,而是食譜少了停下來的步驟。人類做事會疲倦、會察覺怪怪的;電腦不會。它只問條件是不是真的。真的,就繼續。這也是為什麼每次寫迴圈,都要問三件事:開始值是什麼?繼續條件是什麼?每一圈結束後,有沒有讓條件慢慢接近停止?

看 AI 寫的迴圈時,也要用這三問檢查。尤其是 while,因為它不像 for 那樣把計數器放在同一行。你要在大括號裡找那個讓狀態改變的步驟。找不到,就要懷疑它會不會停不下來。會抓這種問題的人,已經不是只會貼 prompt 的使用者,而是在做邏輯審查。

while 每跑一圈都要讓條件更接近停止。
let battery = 3;
while (battery > 0) {
  console.log('掃地中,剩下 ' + battery + ' 格電');
  battery = battery - 1;   // ← 少了這行就會無限迴圈
}
console.log('回充電座');

組合技:在迴圈裡放判斷

真實程式很少只有判斷或只有迴圈,常見的是兩者合在一起:對一份名單逐一檢查,每個人都判斷一次。像老師要找出所有及格學生,就會拿著名單從第一個看到最後一個;每看到一個分數,就問:如果分數大於等於六十,放進及格名單;否則跳過。

這就是「迴圈裡放判斷」。外層的迴圈負責一個一個拿資料,內層的 if 負責決定這筆資料要不要處理。讀這種 code 時,請先分清楚兩件事:迴圈現在看的是哪一筆?判斷正在問這一筆的哪個條件?只要這兩件事清楚,巢狀一層的邏輯就不難。

巢狀(nested)意思是「一個東西包在另一個東西裡」。初學者看到大括號包大括號,常以為難度暴增。其實你可以用生活動作拆開:打開名單,拿第一個人,看分數;拿第二個人,看分數;拿第三個人,看分數。每一輪都是同一套小食譜,只是拿到的資料不同。

這個觀念是後面讀 AI code 的基礎。AI 產出的很多功能,本質都是「拿一串資料,逐筆判斷,符合就處理」。購物車算總價、信件列表找未讀、表單檢查空白欄位,都長得像這樣。你現在練的是追流程:資料怎麼流過迴圈,在哪個條件被留下,最後得到什麼結果。

迴圈逐筆拿分數,if 決定每筆資料的結果。
const scores = [88, 42, 60, 95];
for (const score of scores) {
  if (score >= 60) {
    console.log(score + ' 分:及格');
  } else {
    console.log(score + ' 分:再加油');
  }
}
招牌互動 · flow-runner

Flow Runner:自動售票機流程模擬器

調整輸入,觀察流程亮起的路徑;再切到迴圈模式,看計數器怎麼跑與何時停下。

操作說明:先調整年齡、學生身份與投幣金額,流程節點會即時亮起;再依序完成 A、B、C 三個挑戰。

step 1檢查投幣先看 paid 夠不夠最低門檻。
step 2年齡優惠age < 12 或 age >= 65 就走半票。
step 3學生身份沒有年齡優惠時,再看 isStudent。
step 4輸出結果依照第一個成立的規則輸出票種或退幣。
全票 50 元,找零 0 元

前三個規則都沒中,最後走全票規則。

目前是挑戰 A:請設定 age=10、isStudent=false、paid=25。

操作說明:選一個預設後按播放,觀察每 500ms 推進一次的計數器表格;最後選出哪個設定會無限迴圈。

loop presets

已選安全 for。按播放看 1 到 5 怎麼跑。

哪個設定會無限迴圈?

counter trace

圈數目前值輸出下一步
還沒有播放。選一個預設後按播放。
✓ flow complete 你已經完成售票機三題與無限迴圈判斷。+30 XP 入袋。

純 vibe coder 看到 AI 寫出一大段 if,通常只能祈禱它是對的。你現在會做三個具體動作:先翻成人話、再追條件邊界、最後檢查迴圈會不會停。遇到票價、折扣、權限這類規則,你會特別看 >>=&&|| 有沒有用對。這種能力不是把 AI 當魔法箱,而是把 AI 當實習生交來的食譜逐條驗收。

隨堂測驗 · 5 題

檢查一下這章

下一章預告

下一章會把一組步驟打包成函式,讓你的食譜可以重複呼叫、組合使用。