← JavaScript Learning Path

JAVASCRIPT V2 · FOUNDATIONS · 36

Values、Variables、Types:程式真正保存的是什麼?

這不是一課把 let、const、typeof 背起來就結束。你要建立第一個可持續使用的 JavaScript runtime model:expression 產生 value、binding 讓名稱指向 value、type 影響後續 operator 的行為,而外部輸入常常需要明確轉型。

Learning outcomes

1. Why now:程式的下一步,都建立在「目前有哪些值」

假設我們要做 Grade Tracker。畫面上的名字、分數、是否及格,最後都必須先變成 JavaScript 可以處理的 value。

const studentName = "Anson";
let score = 90;
const passed = true;

這三行看起來簡單,但它們包含四個不同概念:

概念例子你應該問什麼
literal"Anson"、90、truesource code 怎麼直接寫出一個 value?
value字串 Anson、數字 90、Boolean trueruntime 現在真正要處理的資料是什麼?
binding / identifierstudentName、score後面的 code 用哪個名稱再次取得 value?
typestring、number、boolean這個 value 能參與哪些 operation?
核心模型:不要把 variable 想成「一個神秘盒子」。先想成目前 scope 裡的一個名稱,它讓程式能再次取得某個 value。

2. JavaScript 在哪裡做這些事?

source code→JavaScript engine→evaluate expression→value / binding state

在本站的 Browser JavaScript 練習裡,JavaScript engine 讀取程式碼並執行 expression。HTML 不會替你「執行變數」,GitHub 也不會替你決定 score + 5 的結果。

看到下面這一行時:

const total = 10 + 5;
  1. engine 先 evaluate 10 + 5。
  2. 得到 number value 15。
  3. 建立名稱 total。
  4. 讓 total 取得這個 value。

先有 expression result,再有後續 state。這個思路到 function、Promise、React state 都還會用到。

3. Primitive values:先掌握最常遇到的五種

"Anson"     // string
90          // number
true        // boolean
undefined   // undefined
null        // null
Type / value常見來源常見錯誤
stringinput、URL、JSON 文字欄位以為 "10" 已經是 number
number計算、座標、價格、分數得到 NaN 卻繼續計算
booleancomparison、feature state把字串 "false" 當成 Boolean false
undefined沒有 return、找不到 property/result直接讀 undefined.name
null程式刻意表示「目前沒有值」沒有先處理 absence

typeof 是第一個 debugging probe:

console.log(score, typeof score);

它不是型別系統,但非常適合在初學階段確認「runtime 現在手上的東西到底是什麼」。

4. Worked Example A:let 是 state transition,不是裝飾

let score = 80;
score = 90;
score = score + 5;
執行完scoretype發生什麼
line 180number建立 binding
line 290numberreassignment
line 395number讀舊值、計算、再 assignment

score = score + 5 不是數學等式。右邊先讀目前 value 並計算;最後才把結果重新指定給左邊的 binding。

5. const 真正限制的是 binding

const passingScore = 60;

// passingScore = 70;
// TypeError: Assignment to constant variable.

你不能讓 passingScore 重新指向另一個 value。這是初學時最重要的規則。

但之後學 object 時你會看到:

const settings = { theme: "dark" };
settings.theme = "light"; // 可以

因為 binding settings 沒有改成指向另一個 object;改的是 object 裡面的 property。這裡先知道差異即可,40 會正式處理 reference 與 mutation。

6. Worked Example B:為什麼畫面上的 10 + 5 會變成 105?

const rawScore = "10";
const bonus = 5;

console.log(rawScore + bonus); // "105"

+ 不只做數學加法,也能做 string concatenation。當 operand 包含 string 時,結果可能走字串語意。

不要先改 code。先看 evidence:

console.log(rawScore, typeof rawScore);
console.log(bonus, typeof bonus);

如果輸出:

10 string
5 number

現在你已經知道 bug 不在 CSS、不在 loop,而在資料 boundary:rawScore 仍是 string。

7. Explicit conversion:把外部資料轉成你真正要的型別

const rawScore = "10";
const score = Number(rawScore);
const total = score + 5;

console.log(total);        // 15
console.log(typeof total); // "number"

常見 conversion:

CodeResult注意
Number("42")42成功轉 number
Number(" 42 ")42前後空白可被處理
Number("")0常讓初學者意外
Number("abc")NaN不是有效 numeric result
String(42)"42"常用於顯示/組字串
Boolean(0)falsetruthy/falsy 37 再深入

8. Worked Example C:NaN 是 failure evidence,不要把它當普通答案

const rawPrice = "NT$100";
const price = Number(rawPrice);

console.log(price);               // NaN
console.log(Number.isNaN(price)); // true

NaN 仍然具有 JavaScript 的 number type,因此:

console.log(typeof NaN); // "number"

這也是為什麼單看 typeof 有時不夠。當你的 domain 需要「有效數值」,還要檢查 conversion result。

9. Common mistakes:這四種比背 API 更值得記

A. 把 input 看成 number

const qty = input.value; // 通常是 string
const total = qty + 1;

先查 typeof qty,再決定 conversion。

B. 用 const 後又做 reassignment

const score = 80;
score = 90;

如果 state 的確需要重新指定,用 let;如果不需要,就保留 const。

C. conversion failure 後繼續算

const value = Number("abc");
console.log(value + 10); // NaN

看到 NaN 應往資料 boundary 找,不是繼續堆更多 arithmetic。

D. 只看畫面,不看 runtime evidence

畫面顯示「105」只能說結果錯;console.log(value, typeof value) 才開始告訴你原因在哪。

10. Guided exercise:先預測,再跑

let value = "8";
value = Number(value);
value = value * 2;
value = String(value);

console.log(value, typeof value);
  1. 第一行後:value/value type?
  2. 第二行後:value/value type?
  3. 第三行後:value/value type?
  4. 最後輸出是 16 number 還是 16 string?

先寫 trace table,再在 Console 執行。不要直接跳到答案。

11. Independent exercise:做一個小型資料 boundary

寫一個 calculateSubtotal(rawPrice, rawQty):

這題的重點不是乘法,是「外部資料進入 domain calculation 前先 normalize type」。

12. Challenge:找出 bug 在哪個 boundary

const priceInput = "20";
const qtyInput = "3";

const subtotal = priceInput * qtyInput;
const label = "Subtotal: " + subtotal;

console.log(label);

這段目前會得到看似正確的結果,但你仍然要回答:

  1. 為什麼 * 在這裡似乎「自動成功」?
  2. 你是否願意依賴這種 implicit conversion?
  3. 如果 priceInput 變成 "NT$20",failure evidence 會是什麼?

課程後續會逐步減少依賴隱式 coercion,讓資料 contract 更明確。

Project checkpoint:Grade Tracker 的第一個可靠 State

const studentName = "Anson";
const rawScore = "90";
const score = Number(rawScore);

console.log({
  studentName,
  score,
  scoreType: typeof score
});

到這一課結束,你的專案還不需要 DOM、API 或漂亮 UI。真正的完成條件只有:資料進來後,你知道目前 value 是什麼、type 是什麼、哪個 binding 可以重新 assignment、哪個不可以。

13. Vocabulary / Summary

Term精確抓法
literal在 source code 中直接表示 value 的語法
valueruntime 實際處理的資料
identifier程式中的名稱
binding名稱與目前 value 的關聯
assignment把計算後的 value 指定給 binding
typevalue 的資料種類,影響可用 operations
conversion明確把資料轉成另一種 type
NaN數值 operation/conversion 沒得到有效 numeric result 的特殊 number value

14. Further reading

這些是延伸 reference;本站負責學習順序、mental model、可執行練習與 project progression,不直接複製外部教材文字。

Knowledge check:離開前你應該真的能做

  1. 看到 const x = "10",指出 literal、identifier、value、type。
  2. 逐行 trace let x="5"; x=Number(x); x=x+1;。
  3. 解釋 const 為什麼不是「所有資料都 immutable」。
  4. 說明 "5"+1 與 Number("5")+1 為何不同。
  5. 看到 NaN 時,提出至少兩個要檢查的 evidence。
  6. 完成頁面下方 Executable JS mastery lab,不只閱讀答案。