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
- 能區分 string cleaning 與 number conversion。
- 能正確使用
trim、case normalization、includes、slice。 - 能解釋
Number()、parseInt()、parseFloat()的不同風險。 - 能建立 reusable normalization function。
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
- 為什麼
toFixed()的結果不能直接當 number 繼續算? Number("42px")與parseInt("42px", 10)為什麼不同?- 替學生姓名加入 case-insensitive search。
- 測試空白姓名、
"0"、"100"、"101"、"abc"。