先看代码。
为什么字母 A 的长度是 1,emoji 的长度是 2 呢?
这需要从字符集与字符编码开始说起。
Unicode
我们要使用一个字符,它首先应该存在。
Unicode 就是一套定义了全世界字符的字符集。其中的每一个字符都被分配一个唯一的代码点(code point)。而且它还在不断增长。
代码点
代码点只是给字符做的一个映射规则,代码点存储在内存中还需要经过字符编码(character encoding)。
为什么需要这个字符编码呢?
假设不需要字符编码,直接以代码点的方式存储到内存中。那么:
对于内存来说,上面的竖线是不存在的。而它的存储是连续的。如果没有约定的情况下,读取数据不能从时而读两个字节,时而读三个字节。
所以,需要约定一套规则,来存储代码点,这就是编码方式。
HTML 中 <meta charset> 设置的 UTF-8 是也是一种编码方式。
JavaScript 采用的是 UTF-16 的编码方式。
UTF-16
UTF-16 的规则是:将代码点 从 U+0000 到 U+FFFF 编码成两个字节。所以字母 A 还是 0041。
如何获得准确的 length
我们所期望的,其实是以代码点来计算字符串的长度。那么,我们可以使用字符串迭代器进行处理。
String.prototype@@iteratorWhen the @@iterator method is called it returns an Iterator object (25.1.1.2) that iterates over the code points of a String value, returning each code point as a String value.
上面也说到,字符串迭代器是会按代码点返回值。所以我们只需要调用字符串迭代器就可以了。
结语
一个简单的问题,体现不简单的知识点。上面内容只是蜻蜓点水,粗略介绍字符编码的部分知识。真正的字符编码内容远不是三言两语能说清楚。
点击下面题目测试你对这个知识点的理解程度。
提供了一篇写于 2003 年的外文文章,质量很高。正如它的标题所说「绝对是每个软件开发人员必须知道Unicode和字符集」。
https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/