侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

JS 字符串中将两个字节视为一个字符

barwe
2022-04-27 / 0 评论 / 0 点赞 / 896 阅读 / 1,083 字
温馨提示:
本文最后更新于 2022-04-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Unicode 及其实现

Unicode 将每一个字符映射成了一个正整数(称之为 Unicode 码点),由于整数的大小未知,所以它可能占据一个字节或者多个字节,大部分字符串都可以用两个字节的无符号整数来表示,少部分字符需要三个甚至更多字节来表示。

UTF-32,UTF-16,UTF-8 都是 Unicode 的实现方式。

UTF-32 统一用四个字节来表示字符,四个字节可以囊括地球上的所有字符,但是极其浪费。

UTF-16 是一种变长编码方式,用两个字节来表示常用字符,不常用字符用四个字节表示。

UTF-8 也是一种变长编码方式,按照实际需求用一个字节至多个字节来表示字符。

JS 内部的字符编码

JS 内部使用 UTF-16 存储字符,但是操纵字符时又不是完全的 UTF-16。JS 将始终将两个字节视为一个字符,这在大多数情况下不会出现问题。但是当存储的字符 Unicode 码点超过两个字节(大于65535)时,UTF-16 会使用四个字节去存储它。然而 JS 不会考虑这种情况,它仍然认为两个字节表示一个字符,所以这种四字节的特殊字符会被当成两个“字符”处理。

const s = "𠮷"
s.length // 2
s[0] // '\uD842'
s[1] // '\uDFB7'

汉字“𠮷”的 Unicode 码点是 134071 (0x20BB7),对应的 UTF-16 编码占据了四个字节0xD842 0xDFB7

字符串的length方法返回字符数,JS 认为四个字节对应的字符数是 2,而通过下标索引的结果是一个无法被翻译的字符。

charAt

获取字符串指定位置的字符。

两个字节为一个字符,因此在处理含四字节字符的字符串时会得到不正确的结果。

charCodeAt

charAt方法用法类似,只是返回对应字符的 Unicode 十进制码点。

在处理含四字节字符的字符串时会得到不正确的结果。

codePointAt

解决charCodeAt不能正确处理含有四字节字符的字符串的问题。

当遇到四字节字符时,在第一个“字符”处会返回正确的 Unicode 码点,在第二个“字符”处的返回结果与charCodeAt相同。

const s = "𠮷"
s.charCodeAt(0) // 55362 不能翻译的码点
s.charCodeAt(1) // 57271 不能翻译的码点
s.codePointAt(0) // 134071 '𠮷'
s.codePointAt(1) // 57271 不能翻译的码点

遍历字符串

对于两字节字符组成的字符串,下标索引能够正确遍历每个字符。

对于含四字节字符的字符串,遍历字符不能用下标索引,需要用for ... of遍历。

0

评论区