这里有一份简洁的前端知识体系等待你查收,看看吧,会有惊喜哦~如果觉得不错,恳求star哈~
字符编码
计算机内部,所有信息最终都是一个二进制值。
每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。
上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。
ASCII 码规定,最前面的一位统一规定为0,只占用了一个字节的后面7位,一共规定了128个字符的编码。
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。
但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。
至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。所以就出现了其他编码方式,比如简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示 256 x 256 = 65536 个符号。
需要注意的是,GB类的汉字编码与 Unicode 和 UTF-8 是毫无关系的。
编码方式的不同,最大的问题就是容易出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。
可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。
常见的UTF-8、UTF-16 是 Unicode 的实现方式。关于 UTF-8,可以见 资料 。
你可能会好奇:JS 使用哪一种编码?
JS 语言采用Unicode字符集,但是只支持一种编码方法。这种编码既不是UTF-16,也不是UTF-8,更不是UTF-32,而是UCS-2(使用2个字节表示已经有码点的字符)!
UTF-16 跟 UCS-2的关系,简单说,就是UTF-16取代了UCS-2,或者说UCS-2整合进了UTF-16。所以,现在只有UTF-16,没有UCS-2。
之所以 JS 不选择更高级的UTF-16,是因为在 JS 语言出现的时候,还没有UTF-16编码。详见资料 。
综上,可以得出两个结论:
- JS 采用 Unicode 字符集
- 只支持16位的UTF-16编码,不支持32位
这导致的结果就是,JS 操作 String 时,只对2字节的码点有效。类似的方法有:
String.prototype.replace()
String.prototype.substring()
String.prototype.slice()
String.prototype.charAt()
String.prototype.charCodeAt()
要正确处理4字节的码点,可以使用ES6提供的新特性。类似的方法有:
String.fromCodePoint():从Unicode码点返回对应字符
String.prototype.codePointAt():从字符返回对应的码点
String.prototype.at():返回字符串给定位置的字符
细节这里就不赘述,详见资料 。