在 JavaScript 開發中,我們常會需要將一個字串裡的每個字逐一拆解成陣列(字串轉陣列),例如輸入字串 'qqqeee',希望能自動拆解並輸出成陣列 ['q', 'q', 'q', 'e', 'e', 'e'] 以利後續執行 .map()、.filter() 或字數統計。本篇整理 4 種常見的 JavaScript 字串轉陣列寫法,並說明在處理中英文字元與 Emoji 表情符號時的差異。
一、基礎做法:使用 String.prototype.split('')
如果確定輸入的字串只包含一般英數字元、標點符號或常見繁體中文字(基本多文種平面 BMP 字元),最直覺的做法是使用字串內建的 .split('') 方法,並將分隔符號指定為空字串 ''。這樣就會將每個字元拆解成獨立的子字串,最終回傳所需的陣列:
function splitStringToArray(inputString) {
return inputString.split('');
}
// 測試一般英數字串
const input = 'qqqeee';
const output = splitStringToArray(input);
console.log(output);
// 輸出: ['q', 'q', 'q', 'e', 'e', 'e']
// 測試繁體中文字串
console.log('前端開發'.split(''));
// 輸出: ['前', '端', '開', '發']
二、進階做法:解決 Emoji 亂碼的 [...str] 與 Array.from()
雖然 split('') 簡單好用,但它是以 UTF-16 編碼單元(Code Unit) 為單位進行切割。當使用者輸入的字串包含 Emoji 表情符號(例如 😂 或 🚀)或罕見漢字時,因為這些字元在 UTF-16 中是由兩個代理配對(Surrogate Pair)組成,split('') 會把同一個 Emoji 硬生生切成兩半變成亂碼!
此時改用 ES6 的**展開運算子(Spread Operator [...str])**或 Array.from(str),就會改依循字串的可迭代協定(依 Unicode Code Point 碼點)正確拆解:
const textWithEmoji = 'Hi😂👍';
// ❌ 使用 split('') 會把 Emoji 拆成兩個無效的 UTF-16 代理字元
console.log(textWithEmoji.split(''));
// 輸出: ['H', 'i', '\uD83D', '\uDE02', '\uD83D', '\uDC4D'] (出現亂碼)
// ✅ 方法 2:使用 ES6 展開運算子 [...str]
console.log([...textWithEmoji]);
// 輸出: ['H', 'i', '😂', '👍']
// ✅ 方法 3:使用 Array.from(),還可同時傳入第二個參數對每個字元做轉換
const charCodes = Array.from('abc', (char) => char.toUpperCase());
console.log(charCodes);
// 輸出: ['A', 'B', 'C']
三、處理複合型 Emoji(ZWJ 序列):使用 Intl.Segmenter
如果專案需要處理更複雜的「複合型 Emoji」(例如家庭符號 👨👩👧👦 或帶膚色修飾的圖示,底層是由多個 Emoji 透過零寬連字元 ZWJ 組合而成),連 [...str] 也會將它拆成 4 個獨立人頭。這時可以使用現代瀏覽器與 Node.js 原生內建的 Intl.Segmenter 依「視覺字素叢集(Grapheme Cluster)」精準拆解:
function splitByGrapheme(str) {
const segmenter = new Intl.Segmenter('zh-TW', { granularity: 'grapheme' });
return Array.from(segmenter.segment(str), (item) => item.segment);
}
const familyEmoji = 'A👨👩👧👦B';
console.log([...familyEmoji]);
// 輸出: ['A', '👨', '', '👩', '', '👧', '', '👦', 'B'] (被拆散)
console.log(splitByGrapheme(familyEmoji));
// 輸出: ['A', '👨👩👧👦', 'B'] (完整保留每個視覺字元)
四、JavaScript 4 種字串轉陣列方法比較表
| 轉換方法 | 語法範例 | 一般 Emoji (😂) | 適用情境說明 |
|---|---|---|---|
str.split('') | 'abc'.split('') | ❌ 會拆壞成亂碼 | 純英數、ASCII 程式碼、一般中文字串快速拆解 |
展開運算子 [...str] | [...'abc'] | ✅ 正常保留 | 現代專案最推薦的簡潔寫法,可安全處理常見 Emoji |
Array.from(str) | Array.from('abc', fn) | ✅ 正常保留 | 拆解字串的同時,需要立刻對每個字元執行映射轉換(Map) |
Intl.Segmenter | segmenter.segment(str) | ✅ 支援複合 Emoji | 聊天室、社群輸入框等需精準計算人類視覺字數的場景 |
💡 延伸閱讀:將字串拆解成陣列後,若要在 React 中透過
.map()渲染成畫面元素,務必注意每個子元素的key設定,可參考站內另一篇 Encountered Two Children with the Same Key – React Console Warning 原因與唯一 Key 解法;若是要解析網址字串,則可參考 JS 解析 URL:new URL 與 URLSearchParams 屬性對照。
發佈留言