變數與資料 — 有名字的盒子
這章結束你會看懂程式把資料放在哪裡、盒子裡裝的是什麼,以及內容如何被改掉。
開場 · 有標籤的盒子
你在飲料店結帳時,店員不會把每一杯的價格、杯數、折扣都寫在手心上。他會讓收銀機記住:一杯 50 元、買 3 杯、有會員折 10 元。程式也一樣。只要任務不是一秒鐘就結束,電腦就需要地方暫時放資料(data)。變數(variable)就是有標籤的盒子:標籤讓你知道盒子叫什麼,盒子裡放著價格、名字、是否付款、購物清單。這章我們不背術語,先學會看盒子、命名盒子、改盒子內容。當你看得懂盒子,AI 寫出來的程式就不再是一整坨神祕文字,而是一排正在搬資料的收銀機。
1、程式為什麼要記住東西
想像你要請一位很快但很照字面做事的店員結帳。你說:一杯紅茶 30 元,兩杯鮮奶茶各 55 元,今天會員折 10 元。店員如果沒有紙、沒有收銀機、也不能記在腦中,每算一步就會忘記剛才的結果。程式也遇到同一個問題。它執行一行指令,得到一個結果,下一行常常還要用這個結果。這時候就需要一個地方先放著。
這個地方就是變數(variable)。你可以把它看成貼了標籤的盒子。標籤寫著 subtotal,盒子裡放目前小計;標籤寫著 discount,盒子裡放折扣;標籤寫著 finalPrice,盒子裡放最後要收的錢。程式不是因為喜歡英文才這樣寫,而是因為每個盒子都要有名字,下一步才找得到。
盒子的重點有三個。第一,名字要能提醒人裡面裝什麼。第二,內容可以是不同種類的資料。第三,程式往下跑時,可以拿出盒子裡的內容來計算,也可以把新的結果放回盒子。這和 ch01 的食譜觀念連在一起:食譜不是只列動作,還會有「先把切好的洋蔥放旁邊」這種暫存步驟。變數就是程式食譜裡的暫存盒。
對初學者來說,先不要急著記很多語法。你只要問三個問題:這個盒子叫什麼?裡面現在放什麼?下一行有沒有改它?用這三問讀程式,會比一看到英文就放棄穩很多。
再把畫面想細一點:收銀機不只要算一次,它還要在你加點、取消、套用會員折扣時一直更新。沒有變數,每一步都只能從頭重算,錯了也很難追。用盒子記住中間結果,程式才有辦法把複雜任務拆成小步驟,並在每一步留下可以檢查的痕跡。
let teaPrice = 30;
let milkTeaPrice = 55;
let discount = 10;
let total = teaPrice + milkTeaPrice * 2 - discount;
console.log(total);
2、逐字拆開 let price = 50
JavaScript 裡常看到這一行:let price = 50。先把它當成一句很短的指令,不要把它看成數學題。let 的意思是「請建立一個可以改內容的盒子」。price 是盒子的標籤。= 在這裡不是「左右永遠相等」,而是「把右邊的東西放進左邊這個盒子」。50 是真正被放進去的資料。
所以 let price = 50 的白話是:做一個叫 price 的盒子,現在先放數字 50。下一行如果寫 console.log(price),意思是打開 price 盒子,把裡面的東西印出來。你沒有看到盒子本體,但程式會記得它。只要盒子還在可使用的範圍內,後面的指令就能叫它的名字。
初學者常卡在等號。數學課的 = 是判斷兩邊相等;程式裡的 = 多半是賦值(assignment),也就是把值放進盒子。這個差別很重要。你不會說一個空盒子等於 50;你會說,把 50 放到 price 盒子裡。後面如果把 60 放進同一個盒子,盒子還是叫 price,只是內容變了。
變數名稱通常用英文,不是為了炫技,而是因為程式語言的符號系統多半如此。你不需要英文很好,但要練習把名字看成標籤。看到 itemCount,猜它是商品數量;看到 isPaid,猜它跟付款完成有關。好的名字會讓你少問 AI 十次「這行在幹嘛」。
let price = 50;
console.log(price);
price = 60;
console.log(price);
3、資料型別四天王
盒子裡可以放不同種類的東西。第一種是數字(number),例如價格、分數、年齡、數量。它可以加減乘除。第二種是文字(string),例如姓名、商品名稱、地址、提示訊息。文字通常用引號包起來,因為程式要知道這不是變數名,而是一段真的文字。第三種是真假值(boolean),只有 true 或 false,適合表示是否付款、是否登入、是否有會員。第四種是清單(array),像一排小盒子放在大盒子裡,適合存多個品項、多個分數、多個待辦事項。
為什麼要分型別(type)?因為程式對不同資料會做不同事。數字 50 加 10 會得到 60。文字 '50' 加 10,在 JavaScript 裡可能得到 '5010',因為它把 10 接到文字後面。這不是電腦壞掉,而是盒子裡的東西種類不同,操作規則就不同。
生活裡你其實早就懂型別。收銀機上的價格欄不能填「好喝」,因為價格要拿來計算。會員欄通常只需要是或否,因為它要決定能不能折扣。購物籃需要放很多商品,所以它像清單。程式只是把這些分類明確寫出來,讓電腦能穩定照規則做事。
讀 AI 產出的程式時,先盯住型別會很有用。看到 items 後面有中括號,通常是清單。看到 isReady,通常是真假值。看到引號,先把它當文字。你不需要一開始就記完整規格,只要能辨認盒子裡大概是哪一類資料,很多錯誤就會自己浮出來。
練習時可以拿一張訂單來分類:杯數是數字,飲料名稱是文字,是否加冰是真假值,加料項目是清單。這樣分類不是為了考試,而是讓你知道下一步能不能計算、能不能判斷、能不能逐項處理。盒子分類越清楚,後面的程式食譜越不容易亂。
let cupCount = 3;
let drinkName = '珍珠鮮奶茶';
let isMember = true;
let toppings = ['珍珠', '椰果', '布丁'];
console.log(cupCount);
console.log(drinkName);
console.log(isMember);
console.log(toppings[0]);
4、變數會變,不是數學等式
很多人第一次看到 score = score + 10 會皺眉。數學上,一個東西不可能等於自己加 10。可是程式這行不是在證明等式,而是在更新盒子。白話是:先打開 score 盒子,拿出舊分數;把舊分數加 10;再把新分數放回 score 盒子。盒子名稱沒變,內容變了。
這種動作叫重新賦值(reassignment)。它在遊戲分數、購物車總價、倒數計時、庫存數量裡到處都是。玩家答對一題,分數加 10;買走一個商品,庫存減 1;輸入折扣碼,總價被改成折扣後的價格。程式一路往下跑,盒子的內容也跟著任務狀態改變。
這裡要養成一個很實用的讀法:從右邊先讀。看到 score = score + 10,先看右邊 score + 10。此時右邊的 score 指的是舊盒子內容。算完後,才把結果放回左邊的 score。如果舊分數是 20,右邊算出 30,最後盒子裡就是 30。
型別混用也常在這裡出事。假設盒子裡放的是文字 '50',再做 + 10,JavaScript 可能把它當文字接起來,得到 '5010'。所以當 AI 寫的程式結果怪怪的,別只喊錯。先檢查盒子裡是不是你以為的型別。很多 bug 不是公式錯,而是盒子裡放錯種類。
除錯時可以用一張小表追蹤:執行前盒子是什麼,這一行讀了哪些盒子,執行後哪個盒子被改掉。只要把三欄填出來,許多看似神祕的錯誤會變成很普通的搬錯盒子、放錯值、或更新順序錯誤。這種追蹤習慣也會讓你和 AI 合作時更清醒,因為你能指出是哪個盒子開始偏掉,修正也更快、更準。
let score = 20;
score = score + 10;
console.log(score);
let textPrice = '50';
console.log(textPrice + 10);
5、命名是給人看的介面
電腦其實不在乎盒子叫 a 還是 pricePerCup。只要名字合法,它都能跑。但人很在乎。你、同事、未來的你、還有 AI 實習生,都會靠變數名理解這段程式正在處理什麼。壞名字像沒有標籤的紙箱,打開前都要猜;好名字像倉庫標籤,掃一眼就知道內容。
壞名字不一定是錯誤,但會製造誤會。x、data、temp 這種名字有時候可以短暫使用,但如果整段程式到處都是它們,你就很難知道哪個是單價、哪個是數量、哪個是折扣。更糟的是,AI 看到模糊名字,也容易延續模糊邏輯,幫你生出看似能跑、其實難維護的程式。
好的命名有幾個行為準則。用名詞表示資料,例如 pricePerCup、customerName、cartItems。用 is、has、can 開頭表示真假值,例如 isPaid、hasCoupon、canCheckout。清單常用複數,例如 items、scores、orders。這些不是硬背規定,而是讓讀的人少花力氣。
你在請 AI 寫程式時,也可以直接要求它用清楚變數名。不要只說「幫我寫結帳功能」,可以說「變數名稱要能看出單價、數量、折扣、最後總價」。這會讓 AI 實習生的輸出更容易檢查。純 vibe coder 常常只看畫面有沒有動;你會回到盒子,確認資料從哪裡來、叫什麼、何時被改掉。
命名還有一個好處:它會逼你想清楚問題。當你不知道盒子該叫什麼,常常代表你還沒想清楚它裝的是原始輸入、計算中結果,還是最後輸出。先把名字改清楚,再請 AI 繼續補程式,通常比一直重生整段程式更有效。
let pricePerCup = 50;
let cupCount = 3;
let hasCoupon = true;
let finalPrice = pricePerCup * cupCount;
if (hasCoupon) {
finalPrice = finalPrice - 10;
}
console.log(finalPrice);
變數實驗室:三個有名字的盒子
建立盒子、選擇型別、放入資料,再觀察重新賦值如何改變內容。 請依序通過四關;每次建立、更新或選擇後,下方會即時告訴你資料是否放對盒子。
關 1 · 收銀機記憶
建立 A:price number 50;B:drinkName string 珍珠鮮奶茶;C:isPaid boolean false。
關 2 · 分數更新
A 會預載 score number 20。按一次更新,觀察舊值如何被拿出來、計算、再放回同一個盒子。
關 3 · 數字還是文字
左邊是 price number 50,右邊是 textPrice string '50'。兩個都加 10,結果會不同。
關 4 · 命名判斷
每一列選比較好的名字。好名字要讓人一眼看懂盒子裡裝什麼。
看得懂變數名,你就能先抓出 AI code 的資料流:哪個盒子收輸入、哪個盒子存狀態、哪個盒子算最後結果。檢查時不要只問「畫面有沒有跑」,要逐行追蹤盒子內容是否符合期待。遇到怪結果,先查型別,尤其是數字和文字混在一起的地方。下 prompt 時要求 AI 用清楚命名,並請它列出每個重要變數裝什麼,這會直接降低你回頭除錯的成本。
檢查一下這章
下一章預告
下一章會把盒子拿去做決定與重複,讓電腦依條件走不同路、把同一件事做很多次。