了解js字符串的码元与码点

    技术2025-03-03  5

    charCodeAt与codePointAt的用法

    相同点: charCodeAt与codePointAt都是字符串实例的方法,用途都是返回指定索引位字符的Unicode编码 不同点:charCodeAt与codePointAt匹配索引位的规则不一样,charCodeAt是根据码元来匹配,而codePointAt是根据码点来进行匹配的

    码元与码点

    这两点都与计算机编程有关,早期的时候,存储空间比较宝贵,unicode存储文字,16位2进制叫做一个码元(code unit) 计算机发展,对unicode文字进行了扩展,将某些文字扩展到了32位,占了两个码元,兼中国这些二进制的字符叫做码点(code point)

    看两个经典的汉字为例:

    const text = "𠮷"; const tet = "吉" // console.log(/^.$/.test(text)) console.log(text.length)//2 console.log(tet.length)//1 console.log(text.charCodeAt(0))//55362 console.log(text.charCodeAt(1))//55271 console.log(text.codePointAt(0))//134071 console.log(text.codePointAt(1))//57271 console.log(text.charCodeAt(0).toString(16))// \ud842 console.log(text.charCodeAt(1).toString(16))// \udfb7

    从输出结果我们可以看出,𠮷(ji) 的长度竟然不为1,为2。且charAt与codePoint对相同的字符处理的返回结构是不一样的. 这其中的原因就是charCodeAt是以一个码元为一个索引,codePointAt是以一个码点为一个索引进行处理的。

    特别注意:码点可以是一个码元,也可以是两个码元。

    字符串的length属性返回的是码。所以在一些字符串如果要处理长度的时候要注意这一点

    我们从控制台输出结果可知道,𠮷(ji)的Unicode编码是\ud842\udfb7,占用了两个码元。

    𠮷这个字的Unicode编码是\ud842\udfb7,占用了两个码元。

    所以当用charCodeAt(0)是匹配0位的码元,也就是返回给我们55362。

    当用codePointAt(0)是匹配0位的码元,codePointAt能识别出字符串的码点,所以反回134071。

    总结

    charCodeAt是以码元单位进行处理的,也就是按照每16位2进制数为单位。一个16位2进制就是一位,所以处理不了Unicode扩展码字符(32位2进制)。它会把32位2进制数当成两个16位2进制数处理。 codePointAt也是以码元为单位来处理的。与charCodeAt不同的是,当处理当前位码元时,如果 超过了位进制数值得上限时会以32位2进制数来处理

    也可以通过codePointAt来判断当前字符是是32位的码点还是16位的码元

    function is32bit(char){ //如果码点大于了16位二进制的最大值,则其是32位的 return char.codePointAt(0) > 0xffff; } console.log(is32bit("吉"))//false console.log(is32bit("𠮷"))//true

    同样的,也可以通过这个方法来判断以字符串真实的长度(码点的长度)

    function getLengthOfCodePoint(text) { var len = 0; for (let i = 0; i < text.length; i++) { //i在索引码元 if (is32bit(text, i)) { //当前字符串,在i这个位置,占用了两个码元 i++; } len++; } return len;//1 }
    Processed: 0.008, SQL: 9