Unicode 是一种用于表示和管理世界上大多数书写系统的文本的标准。几乎所有处理文本的现代软件都支持 Unicode。该标准由 Unicode 协会维护。该标准每年都会发布新版本(包含新的表情符号等)。Unicode 1.0.0 版本于 1991 年 10 月发布。
理解 Unicode 的两个关键概念
第一版 Unicode 具有 16 位代码点。从那时起,字符数量大幅增加,代码点的大小扩展到 21 位。这 21 位被划分为 17 个平面,每个平面 16 位
平面 1-16 称为辅助平面或星形平面。
让我们检查几个字符的代码点
> 'A'.codePointAt(0).toString(16)'41'
> 'ü'.codePointAt(0).toString(16)'fc'
> 'π'.codePointAt(0).toString(16)'3c0'
> '🙂'.codePointAt(0).toString(16)'1f642'
代码点的十六进制数告诉我们,前三个字符位于平面 0(16 位以内),而表情符号位于平面 1。
编码代码点的主要方式是三种Unicode 转换格式 (UTF):UTF-32、UTF-16、UTF-8。每种格式末尾的数字表示其代码单元的大小(以位为单位)。
UTF-32 使用 32 位来存储代码单元,每个代码点对应一个代码单元。此格式是唯一使用固定长度编码的格式;所有其他格式都使用不同数量的代码单元来编码单个代码点。
UTF-16 使用 16 位代码单元。它按如下方式编码代码点
BMP(Unicode 的前 16 位)存储在单个代码单元中。
星形平面:BMP 包含 0x10_000 个代码点。鉴于 Unicode 总共有 0x110_000 个代码点,我们仍然需要编码剩余的 0x100_000 个代码点(20 位)。BMP 有两个未分配的代码点范围,提供了必要的存储空间
换句话说,末尾的两个十六进制数字贡献了 8 位。但只有当 BMP 以以下 2 位数字对之一开头时,我们才能使用这 8 位
每个代理,我们可以在 4 对之间进行选择,这就是剩余 2 位的来源。
因此,每个 UTF-16 代码单元始终是前导代理、后导代理或编码 BMP 代码点。
以下是两个 UTF-16 编码代码点的示例
🙂
) 在星形平面中,由两个代码单元表示:0xD83D 和 0xDE42。UTF-8 具有 8 位代码单元。它使用 1–4 个代码单元来编码一个代码点
代码点 | 代码单元 |
---|---|
0000–007F | 0bbbbbbb(7 位) |
0080–07FF | 110bbbbb,10bbbbbb(5+6 位) |
0800–FFFF | 1110bbbb,10bbbbbb,10bbbbbb(4+6+6 位) |
10000–1FFFFF | 11110bbb,10bbbbbb,10bbbbbb,10bbbbbb(3+6+6+6 位) |
注意
三个例子
字符 | 代码点 | 代码单元 |
---|---|---|
A | 0x0041 | 01000001 |
π | 0x03C0 | 11001111, 10000000 |
🙂 |
0x1F642 | 11110000, 10011111, 10011001, 10000010 |
Web 开发中使用的 Unicode 编码格式是:UTF-16 和 UTF-8。
ECMAScript 规范在内部将源代码表示为 UTF-16。
JavaScript 字符串中的字符基于 UTF-16 代码单元
> const smiley = '🙂';
> smiley.length2
> smiley === '\uD83D\uDE42' // code unitstrue
有关 Unicode 和字符串的更多信息,请参阅§20.7 “文本的原子:代码点、JavaScript 字符、字素簇”。
如今,HTML 和 JavaScript 几乎总是编码为 UTF-8。
例如,这就是 HTML 文件现在通常的开头方式
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
···
对于在 Web 浏览器中加载的 HTML 模块,标准编码也是 UTF-8。
当我们考虑到世界上的各种书写系统时,字符的概念变得非常复杂。这就是为什么有几个不同的 Unicode 术语都以某种方式表示“字符”:代码点、字素簇、字形等。
在 Unicode 中,代码点是文本的原子部分。
但是,字素簇最接近于屏幕或纸张上显示的符号。它被定义为“一个水平可分割的文本单元”。因此,官方 Unicode 文档也将其称为用户感知字符。编码一个字素簇需要一个或多个代码点。
例如,梵文kshi由 4 个代码点编码。我们使用Array.from()
将字符串拆分为包含代码点的数组(有关详细信息,请参阅§20.7.1 “使用代码点”)
旗帜表情符号也是字素簇,由两个代码点组成——例如,日本国旗
符号是一个抽象概念,是书面语言的一部分
概念与其表示之间的区别很微妙,在谈论 Unicode 时可能会变得模糊。
更多关于字素簇的信息
有关更多信息,请参阅 Manish Goregaokar 的“让我们停止将含义归因于代码点”。
测验
请参阅测验应用程序。