JavaScript 内部,字符以 UTF-16 的格式储存,每个字符固定为2个字节。对于那些需要4个字节储存的字符(Unicode 码点大于0xFFFF的字符),JavaScript 会认为它们是两个字符。
解决:codePointAt() 方法,可以检查字符长度是2个字节还是4个字节
function is32Bit(c) {
return c.codePointAt(0) > 0xFFFF;
}
is32Bit("𠮷") // true
is32Bit("a") // false
注意如果用index取的话,一个4字节的字符会被认为长度为2
let s = '𠮷a';
s.codePointAt(0) // 134071
s.codePointAt(1) // 57271,把‘𠮷’的后两位字符拆开了
s.codePointAt(2) // 97
charCodeAt 和 codePointAt 区别
如果 Unicode 码点不能用一个 UTF-16 编码单元表示(因为它的值大于0xFFFF),则所返回的编码单元会是这个码点代理对的第一个编码单元) 。如果你想要整个码点的值,使用 codePointAt()。
'𠮷'.codePointAt().toString(2).length //18
'𠮷'.charCodeAt().toString(2).length //16