codePointAt()
JavaScript 内部,字符串以UTF-16的格式存储,每个字符固定为2个字节.对于那些需要4个字节存储的字符,(Unicode码点大于
0xFFFF的字符) , JavaScript会认为它们是两个字符。
> var s = "𠮷"
undefined
> s
'𠮷'
> s.length
2
> s.charAt(0)
'�'
> s.charAt(1)
'�'
> s.charCodeAt(0)
55362
> s.charCodeAt(1)
57271
>
上面代码中, 汉字“”的码点是 0x20BB7 , UTF-16编码为 0xD842 0xDFB7 (十进制为55362 57271) , 需要4个字节储存。 对
于这种4个字节的字符, JavaScript不能正确处理, 字符串长度会误判为2, 而且 charAt 方法无法读取整个字
符, charCodeAt 方法只能分别返回前两个字节和后两个字节的值。
ES6提供了 codePointAt 方法, 能够正确处理4个字节储存的字符, 返回一个字符的码点。
> var s = "𠮷s"
undefined
> s
'𠮷s'
> s.codePointAt(0)
134071
> s.codePointAt(1)
57271
> s.codePointAt(2)
115
>
codePointAt 方法的参数, 是字符在字符串中的位置(从0开始) 。 上面代码中, JavaScript将“a”视为三个字
符, codePointAt方法在第一个字符上, 正确地识别了“”, 返回了它的十进制码点134071(即十六进制的 20BB7 ) 。 在第二
个字符(即“”的后两个字节) 和第三个字符“a”上, codePointAt 方法的结果与 charCodeAt 方法相同。
总之, codePointAt 方法会正确返回32位的UTF-16字符的码点。 对于那些两个字节储存的常规字符, 它的返回结果
与 charCodeAt 方法相同。
使用 for...of 循环,正确识别 32位的UTF-16字符:
> var s = "𠮷s"
undefined
> for(let ch of s) {
... console.log(ch.codePointAt(0))
... }
134071
115
String.fromCodePoint()
可以识别大于 0xFFFF 的码点,功能和 codePointAt() 相反
> String.fromCodePoint(0x20BB7)
'𠮷'