EcmaScript 语言规范的第 8.4 节说
当一个字符串包含实际的文本数据时,每个元素都被认为是一个 UTF-16 代码单元。无论这是否是字符串的实际存储格式,字符串中的字符都按其初始代码单元元素位置编号,就好像它们使用 UTF-16 表示一样。对字符串的所有操作(除非另有说明)都将它们视为未区分的 16 位无符号整数序列;他们不确保生成的字符串是规范化的形式,也不确保语言敏感的结果。
因此,您需要将补充代码点编码为一对 UTF-16 代码单元。
文章“Java 平台中的补充字符”很好地描述了如何做到这一点。
UTF-16 使用一个或两个无符号 16 位代码单元的序列来编码 Unicode 代码点。值 U+0000 到 U+FFFF 以一个 16 位单元编码,具有相同的值。补充字符用两个代码单元编码,第一个来自高代理范围(U+D800 到 U+DBFF),第二个来自低代理范围(U+DC00 到 U+DFFF)。这在概念上似乎类似于多字节编码,但有一个重要区别:值 U+D800 到 U+DFFF 保留用于 UTF-16;没有字符被分配给它们作为代码点。这意味着,软件可以为字符串中的每个单独的代码单元判断它是否代表一个单元字符,或者它是双单元字符的第一个单元还是第二个单元。这是对一些传统的多字节字符编码的重大改进,
下表比较了几个字符的不同表示:
代码点/UTF-16 代码单元
U+0041 / 0041
U+00DF / 00DF
U+6771 / 6771
U+10400 / D801 DC00
一旦您知道 UTF-16 代码单元,您就可以使用 javascript 函数创建一个字符串String.fromCharCode
:
String.fromCharCode(0xd801, 0xdc00) === ''