-24

我正在编写一个处理表情符号的计算机程序。我对表情符号变体如何在内部表示感兴趣。

诸如这些竖起大拇指的表情符号看起来是相同的字符,但具有不同的特征,例如肤色。此外,这些字符似乎占用了相对大量的内存:

console.log('a'.length) // 1
console.log(''.length) // 4

这些字符在内部是如何表示的?

4

1 回答 1

8

TLDR

在 Unicode 中,带有肤色的表情符号是一种变体形式,为基本字符呈现不同的描述(字形)。

一个表情符号,例如中深肤色的竖起大拇指符号 () 是由一个由基本字符(竖起大拇指符号 )组成的字素组成的,后面紧跟一个变体选择器 非间距标记(中等-深色肤色)。

细节

“”中有多少个字符?

一。

一个字符的 Unicode 定义是:

(1) 书面语言中具有语义价值的最小组成部分;指的是抽象的含义和/或形状,而不是特定的形状(另见字形),尽管在代码表中,某种形式的视觉表示对于读者的理解是必不可少的。(2) 抽象字符的同义词。(3) Unicode 字符编码的基本编码单位。(四)汉源表意文字的英文名称。

“”具有单一的、不可分割的抽象含义(“竖起大拇指”),因此符合单个字符的定义。


“”中有多少个字素?

一。

字素的 Unicode 定义

(1) 在特定书写系统的上下文中,最小的独特书写单元。例如,‹b›和‹d›在英语书写系统中是不同的字素,因为存在 big 和 dig 等不同的词。相反,小写斜体字母 a 和小写罗马字母 a 不是不同的字素,因为没有根据这两种不同形式来区分单词。(2) 用户认为的角色。

存在一个字素:竖起大拇指符号 (U+1F44D),后跟一个非间距标记:中深肤色变化选择器(U+1F3FE)。变体选择器表示应该使用不同的字形来描述基本字符

这种基本字符(字素基)和变体选择器的组合称为字素簇。请注意,变体选择器不会像重音符号那样组合标记。

关于组合的 Unicode 规范部分

字素簇通常以字素基开始,然后延伸到任何后续的非间距标记序列。字素簇与文本渲染和编辑中的光标放置和文本选择等过程最直接相关,但也可能与比较和搜索相关。

和,

对于许多进程,字素簇的行为就好像它是一个具有与其字素基相同属性的单个字符。实际上,非间距标记以图形方式应用于基础,但不会更改其属性。

因此,在这种情况下,我们将一个字形和一个非间距标记组合成一个字形簇,以形成一个字形(对特定字符的描述):

 +  makes 

“”中有多少个代码点?

二。

代码点的 Unicode 定义是:

(1) Unicode 代码空间中的任何值;即从0到10FFFF16的整数范围。(参见第 3.4 节字符和编码中的定义 D10。)并非所有代码点都分配给编码字符。请参阅代码点类型。(2) 任何编码字符集中的字符的值或位置。

这里我们有两个来自 Unicode 代码空间的值,所以我们有两个代码点。

在 JavaScript 中,String#[Symbol.Iterator]迭代代码点,使我们能够“看到”代码点:

console.log([...''])


“”中有多少个代码单元?

四个(在 UTF-16 中)。

代码单元是编码代码点的一部分的存储单元。

这个字符中的两个码位都需要超过 16 位来表示,因此在 UTF-16 中,每个码位有两个码位,一共有四个码位。

\ud83d\udc4d\ud83c\udffe

"".length // 4
console.log('\ud83d\udc4d\ud83c\udffe')


“”中有多少字节?

八。

在 UTF-16 中,有四个 16 位代码单元,在这个字符中构成 8 个字节。


“”中有多少个代理对?

二。

代理对用于 UTF-16。该术语指的是 2 个代码单元的序列,它们一起形成一个代码点。

UTF-16 是一种可变宽度的 2 字节或 4 字节字符编码。代码点(字符)根据代码点编号以 2 字节或 4 字节编码。

对于 0x0 和 0xFFFF 之间的代码点(即 0 到 65,536),可以将代码点编码为单个代码单元(16 位)。对于 0x10000 和 0x10FFFF 之间的代码点,代码点需要 2 个代码单元(一个 16 位高字和一个 16 位低字)。

在 UTF-16 中,两个代码单元一起形成了所谓的代理对。

有两个16 位代码单元的代理对,形成两个代码点。

于 2020-02-11T12:45:15.613 回答