📋 目錄
這是 TC39 新語法深度解析系列的第八篇。Pattern Matching(模式匹配)是一個在函數式編程語言(Haskell、Scala、Rust、Elixir)中常見的概念,現在即將進入 JavaScript。⚠️ 注意:本文內容基於 Stage 2 提案,可能會有變更。
⚠️ 當前狀態
Pattern Matching 目前是 Stage 2,這意味著:
- 語法可能會有變更
- 還沒有瀏覽器原生支援
- 需要 Babel 外掛才能試用
# 用 Babel 試用
npm install --save-dev @babel/plugin-proposal-pattern-matching
Pattern Matching 解決什麼問題?
// 過去:複雜的條件判斷
function processResponse(data) {
if (data.type === 'success') {
if (data.value) {
return renderSuccess(data.value);
} else {
return renderEmpty();
}
} else if (data.type === 'error') {
return renderError(data.message);
} else if (data.type === 'loading') {
return renderLoading();
} else {
return renderUnknown(data);
}
}
Pattern Matching 把這個變成:
const result = match (data) {
when ({ type: 'success', value: v }) -> renderSuccess(v)
when ({ type: 'success' }) -> renderEmpty()
when ({ type: 'error', message: m }) -> renderError(m)
when ({ type: 'loading' }) -> renderLoading()
else -> renderUnknown(data)
};
基本語法
const shape = { kind: 'circle', radius: 10 };
const area = match (shape) {
when ({ kind: 'circle', radius: r }) -> Math.PI * r * r
when ({ kind: 'rectangle', width: w, height: h }) -> w * h
when ({ kind: 'triangle', base: b, height: h }) -> b * h / 2
else -> 0
};
注意:match 是一個表達式,不是語句——它可以返回值,可以直接在賦值右側使用。
Guard:加了條件的模式
const score = { type: 'exam', value: 85, grade: 'B' };
const description = match (score) {
when ({ type: 'exam', value: v }) v >= 90 -> 'A grade'
when ({ type: 'exam', value: v }) v >= 80 -> 'B grade'
when ({ type: 'exam', value: v }) -> 'Below B'
else -> 'Not an exam'
};
when 後面的第二個表達式是 guard——必須為 true 才匹配。
與 TypeScript discriminated union 的比較
// TypeScript discriminated union
type Result =
| { type: 'success'; data: User }
| { type: 'error'; message: string }
| { type: 'loading' };
function process(r: Result): string {
switch (r.type) { // switch 仍然是語句,不能在表達式位置用
case 'success': return r.data.name;
case 'error': return r.message;
case 'loading': return '...';
}
}
Pattern Matching 可以在表達式位置使用,而且能直接解構:
// Pattern Matching(提案語法)
function process(r) {
return match (r) {
when ({ type: 'success', data: { name } }) -> `Hello, ${name}!`
when ({ type: 'error', message }) -> `Error: ${message}`
when ({ type: 'loading' }) -> 'Loading...'
};
}
實際應用:FSM 轉換
// 有限狀態機:燈的狀態轉換
function transition(state, event) {
return match ([state, event]) {
when (['off', 'turn_on']) -> 'on'
when (['on', 'turn_off']) -> 'off'
when (['on', 'dim']) -> 'dim'
when (['dim', 'brighten']) -> 'on'
else -> state // 無效轉換,保持當前狀態
};
}
限制與批評
提案目前有一些限制:
- 沒有 exhaustive matching 檢查(無法像 Rust 一樣確保所有情況都被處理)
- 只能匹配特定模式,不支援任意 boolean 表達式
else是必需要的(目前提案沒有 exhaustive 檢查)
總結
Pattern Matching 是一個** Stage 2 尚未確定的提案**。如果它在未來達到 Stage 4,它會成為 JavaScript 函數式編程工具箱中的重要武器。目前:
// 試用(需要 Babel)
npm install @babel/plugin-proposal-pattern-matching
這是 TC39 新語法深度解析系列的第八篇。下一篇:Pipeline Operator — 用 |> 寫出更易讀的資料轉換鏈。
延伸閱讀
- 2026 前端框架比較 — 框架對新語法的支援比較
本文基於 TC39 Pattern Matching 提案(Stage 2)整理,語法可能會有變更。