揭秘 JS 中的字符、代码单元和码点
2023-10-16 04:18:00
在 JavaScript 中,字符串是基本的数据类型之一,它可以表示一系列字符。但是,字符串的内部表示形式却并不像我们想象的那么简单。在 JavaScript 中,字符串实际上是采用 UTF-16 编码的,这意味着字符串本质上是由一个个 16 位值(16-bits values)组成的序列。这些 16 位值被称为“代码单元”(code units),而字符串中的每个“元素”从技术上将不是一个“字符”,而是一个“代码单元”。
为什么 JavaScript 要使用 UTF-16 编码呢?这是因为 UTF-16 编码能够表示世界上绝大多数的字符,包括各种语言的字母、数字、符号等。UTF-16 编码的范围非常广,它可以表示超过 100 万个字符。
那么,代码单元和字符之间有什么区别呢?代码单元是字符串的内部表示形式,而字符是字符串的外部表示形式。代码单元是一个 16 位的值,而字符是一个人类可读的符号。例如,字母 “A” 的代码单元是 0x0041,而字母 “A” 的字符是 “A”。
在大多数情况下,代码单元和字符是一一对应的。也就是说,一个代码单元对应一个字符。但是,也有一些例外情况。例如,某些字符可能需要两个代码单元来表示。这些字符被称为“代理对”(surrogate pairs)。代理对的第一个代码单元称为“高代理”(high surrogate),第二个代码单元称为“低代理”(low surrogate)。
// 创建一个字符串
const str = "Hello, world!";
// 获取字符串的长度
const length = str.length;
// 遍历字符串中的每个字符
for (let i = 0; i < length; i++) {
// 获取当前字符的代码单元
const codeUnit = str.charCodeAt(i);
// 获取当前字符
const char = str.charAt(i);
// 打印当前字符的代码单元和字符
console.log(`代码单元:${codeUnit}, 字符:${char}`);
}
上面这段代码创建了一个字符串,然后获取字符串的长度。接下来,代码使用 charCodeAt()
方法获取字符串中每个字符的代码单元,并使用 charAt()
方法获取字符串中每个字符。最后,代码将每个字符的代码单元和字符打印到控制台。
输出结果如下:
代码单元:72, 字符:H
代码单元:101, 字符:e
代码单元:108, 字符:l
代码单元:108, 字符:l
代码单元:111, 字符:o
代码单元:44, 字符:,
代码单元:32, 字符:
代码单元:119, 字符:w
代码单元:111, 字符:o
代码单元:114, 字符:r
代码单元:108, 字符:l
代码单元:100, 字符:d
代码单元:33, 字符:!
从输出结果中我们可以看到,代码单元和字符是一一对应的。但是,需要注意的是,某些字符可能需要两个代码单元来表示。例如,中文汉字“中”的代码单元是 0x4e2d,而中文汉字“国”的代码单元是 0x56fd。
理解代码单元和字符之间的区别非常重要,因为这有助于我们更好地理解 JavaScript 中的字符串处理。例如,当我们使用 charCodeAt()
方法获取字符串中某个字符的代码单元时,我们需要知道该字符是否需要两个代码单元来表示。如果需要,我们需要使用两个 charCodeAt()
方法来获取该字符的代码单元。
此外,理解代码单元和字符之间的区别也有助于我们更好地理解 JavaScript 中的正则表达式。正则表达式是一种用于匹配字符串的模式。正则表达式中的某些元字符,例如 \w
和 \d
,是根据代码单元来匹配字符的。因此,我们需要知道代码单元和字符之间的区别,才能正确地使用正则表达式。