← JavaScript Course

PRACTICAL JAVASCRIPT · 57

String / Number:資料進到程式後,第一件事通常是清理

真實專案不會永遠收到乾淨資料。表單 input、URL query、CSV、API 欄位都可能帶空白、大小寫差異或字串型數字。這一課把「raw input → normalized data」當成一個明確 pipeline。

Why now

36–43 已經會處理 state、DOM 與 API。現在問題變成:使用者輸入的資料通常不是你真正想拿來計算的格式。

raw input→ normalize →validated value→ business logic →render/store

Learning outcomes

1. String cleanup:先把資料變成一致格式

const rawName = "  Anson Hung  ";

const name = rawName.trim();

console.log(name);
// "Anson Hung"
const query =
  input.value
    .trim()
    .toLowerCase();

const matches =
  title.toLowerCase().includes(query);

搜尋時通常不是把資料改成小寫保存,而是在 comparison boundary 做 normalization。

2. split / slice / replace:結構化文字

const csv = "JavaScript,90,pass";

const parts = csv.split(",");

const title = parts[0];
const scoreText = parts[1];

const shortTitle = title.slice(0, 4);
const cleaned = csv.replace("pass", "PASS");

如果資料格式已經複雜到需要大量手工 split,通常就要思考 JSON / parser / schema,而不是無限堆字串切割。

3. Number conversion:不要讓 coercion 偷偷替你決定

const raw = "90";

const score = Number(raw);

console.log(score + 5);
// 95
寫法例子重點
Number(x)Number("42")要求整個值能轉成數字
parseInt(x, 10)parseInt("42px", 10)從前面解析整數
parseFloat(x)parseFloat("3.14kg")從前面解析浮點數
設計問題:如果輸入應該是純數字,Number("42px") 回 NaN 反而可能更符合 validation 需求;不要因為 parseInt「比較寬鬆」就一律使用。

4. NaN:conversion 失敗仍然是 number type

const score = Number("abc");

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

console.log(Number.isNaN(score));
// true

所以只檢查 typeof score === "number" 不夠。

5. Formatting ≠ numeric value

const average = 87.456;

const display = average.toFixed(1);
// "87.5" ← string

格式化通常放在 presentation boundary;內部計算仍保存 number。

Project checkpoint:Grade Tracker 的 input pipeline

function normalizeStudentInput(
  rawName,
  rawScore
) {
  const name = rawName.trim();
  const score = Number(rawScore);

  if (!name) {
    throw new Error("Name is required");
  }

  if (
    Number.isNaN(score)
    || score < 0
    || score > 100
  ) {
    throw new Error("Invalid score");
  }

  return { name, score };
}
DOM stringsnormalizevalidate{ name, score }

Knowledge check

  1. 為什麼 toFixed() 的結果不能直接當 number 繼續算?
  2. Number("42px") 與 parseInt("42px", 10) 為什麼不同?
  3. 替學生姓名加入 case-insensitive search。
  4. 測試空白姓名、"0"、"100"、"101"、"abc"。