JavaScript 字符串按字符拆分

split('')`、展开运算符和 `Array.from()` 在 Unicode 字符串拆分上的差异。

#type / concept #status / growing #resource / javascript #resource / ecmascript

[!info] related notes

JavaScript 字符串按字符拆分

这个问题的核心不是“怎么拆字符串”,而是“按什么单位拆”。split('') 按 UTF-16 代码单元拆,[...str]Array.from(str) 则按字符串迭代器产出的码位拆。

先看最直观的差异

const str = 'a🚀b';

str.split('');
// ['a', '\uD83D', '\uDE80', 'b']

[...str];
// ['a', '🚀', 'b']

Array.from(str);
// ['a', '🚀', 'b']

为什么 split('') 会出问题

JavaScript 字符串底层基于 UTF-16。像 🚀 这样的字符会占用两个代码单元。

split('') 只会机械地逐个代码单元切开,所以会把代理对拆散。

为什么 [...str]Array.from(str) 更稳妥

它们消费的是字符串默认迭代器,而字符串迭代器会按码位产出值,所以能正确处理大多数超出 BMP 的字符。

这也是它们和 ecmascript-iterators-and-generators 直接相关的地方。

但这里还有一个边界

[...str]Array.from(str)split('') 更好,但它们也不等于“完整的用户感知字符切分”。

比如:

  • 旗帜 emoji
  • 家庭 emoji
  • 某些带组合附加符号的字符

这些可能由多个码位组成一个肉眼看到的字符。真要按“用户看到的一个字符”切分,往往要看 Intl.Segmenter 等更高层方案。

什么时候用哪种方式

  • 已知只处理 ASCII 或简单英文时,split('') 可以工作
  • 只想避免代理对被拆坏时,优先 [...str]Array.from(str)
  • 需要严格的人类可见字符分段时,考虑 Intl.Segmenter

延伸阅读

创建于 2026/3/3 更新于 2026/5/27