为了生成与观察到的不同图形符号相对应的 Unicode 字符串的计数,需要对原始字符串执行多次还原操作。
我们需要删除代理和变体编码,以及适当的修饰符。我们还需要考虑零宽度连接器 (ZWJ) 连接器。最终结果可以在index.ts文件或本文档的底部看到。
我们计算我们所看到的
但 JavaScript 却没有
一段感知到的文本与其离散部分的总和一样长。
我们期望任何我们认为是单一单位的东西——字母、标点符号或其他独特的图形符号——也应该被视为不可分割的,并被一一计数,直到我们到达终点。
直观上,这似乎很清楚。正如该单词Hello有 5 个不同的字母一样,以下每个表情符号:、❤️、、♀️ 或 都被视为不同的、单独的单位。因此,计算字符串的各个部分Hello 应等于length7。
但 JavaScript 中并不是这样的。
"".length; // => Expected 1, got 4.
"".length; // => Expected 1, got 11.
"♀️".length; // => Expected 1, got 7.
"Hello ".length; // => Expected 7, got 10.
"Family ".length; // => Expected 8, got 18.
为什么会出现这种差异?
从编码到外观
众多皆为一
上面的原始长度结果实际上代表了对生成观察到的符号所需的 Unicode 字符组合的正确评估。该length操作并不计算我们立即期望的结果 - 最终的视觉单位结果 - 而是组合在一起构成最终外观的所有零碎内容:一只苍白的手,一个家庭,一个打水球的女人。
简单的符号实际上是由更原始的符号组成的,这应该是非常熟悉的想法。当我们学习写字时,我们发现每个字母都是由不同的线条组成的。单个字母I由单线绘制,单个字母H由三条不同的线组合而成|, -, |。
输出其他符号(例如表情符号)也可能需要组合。挥手表情符号可以有肤色修饰符。水球运动员的性别(女性)可以是中等深色肤色。心形可以有红色变体。等等…
为了帮助我们理解如何计算我们所看到和感知的不同事物,人们提出了不同的解释、建议和策略,