为什么'\u{1F680}'==='\uD83D\uDE80'
首先需要了解JS代码里面的unicode编码字符的语法是:\uXXXX.这种表示法只能记录码点在\u0000~\uFFFF之间(即0~65535)的字符,超出这个范围的字符,必须用两个双字节的形式表示.
对于大于0xFFFF(即65535 0x即16进制)的字符,先减去0x10000(即65536),然后转换为20bit的二进制数,然后分别填充两个码点空出的10bit,这就是需要两个码点字符的保存方式。
码点一: 0b110110(0b即二进制)
码点二: 0b110111
但是为什么是这两个码点呢?这与Unicode编码的设计者的设计有关.Unicode编码0xD800-0xDFFF,共2048个码位,是一个被称作代理区(Surrogate)的特殊区域.代理区的目的用两个UTF-16字符表示0~0xFFFF(即0~65535)以外的字符。所有大于0xFFFF的码需要使用代理区的码点。
目前Unicode最大的码位是0x10FFFF(即1114111)
0x010000-0x10FFFF,需要使用2个代理码元表示,第一个码元为0xD800-0xDBFF(高位)范围是:1101 1000 0000 0000到1101 1011 1111 1111,第二个码元为0xDC00-0xDFFF(低位)范围是:1101 1100 0000 0000到1101 1111 1111 1111.
| 十进制 | Unicode编码 | 说明 | 说明 |
|---|---|---|---|
| 55296-56191 | 0xD800-0xDB7F(896个) | High Surrogates | 高位替代 |
| 56192-56319 | 0xDB80-0xDBFF(128个) | High Private Use Surrogates | 高位专用替代 |
| 56320-57343 | 0xDC00-0xDFFF(1024个) | Low Surrogates | 低位替代 |
接下来我们把Unicode编码>65535的记为U,我们先计算U'=U-0x10000,然后将U'写成二进制形式:yyyy yyyy yyxx xxxx xxxx,那么U的UTF-16编码(二进制)就是:110110yyyyyyyyyy110111xxxxxxxxxx.
了解前边两个码点后,那么 0x1F680如果用两个双字节表示呢
先计算
0x1F680-0x10000结果为0xF680(0x1F680-0x10000).toString(16)
0xF680转化为2进制结果为0b1111 0110 1000 00000xf680.toString(2)
将上一步结果补全为20位的二进制数
0b0000 1111 0110 1000 0000(前面加4个0)- 填充两个码点空出的
10bit,第一个码点填充为0b1101 1000 0011 1101第二个码点填充为0b1101 1110 1000 0000 - 将两个填充后的码点转化为十六进制即为
0xD83D和0xDE80.

即'\u{1F680}'==='\uD83D\uDE80'