将Unicode字符转换为十六进制会导致额外字节

时间:2016-09-29 17:27:32

标签: javascript unicode hex

这是我用来转义多字节unicode字符的代码。

let sample = '1F3C4-1F3FB-200D-2640-FE0F'; //‍♀️
let characters = String.fromCodePoint(...sample.split('-').map(code => parseInt(code, 16)));
let codes = '';
for(let i=0;i<characters.length;i++){
    codes += (i === 0 ? '' : '-') + characters.codePointAt(i).toString(16).toUpperCase();
}
console.log(codes); //1F3C4-DFC4-1F3FB-DFFB-200D-2640-FE0F

从示例中可以看出,转换会在结果中产生2个额外字节。

我的代码有什么问题吗?我该如何解决?

1 个答案:

答案 0 :(得分:1)

显然,codePointAt函数给出“一个数字,表示给定索引处字符的代码单元值”。但是,索引与charCodeAt的索引相同,因此如果该索引位于代理对的中间(例如\uD83C\uDFC4的{​​{1}}),则只会给出后半部分代理人对。

您可以在输出中看到这一点,因为额外的字符出现在具有代理对(\u{1F3C4}个字符)的两个字符之后,并且它们是其前一个代理对的后半部分。

如果您使用的是ES6,您可以使用spread运算符来拆分unicode字符(而不是像U+1xxxx那样拆分代理对):

string.split()