揭开谜团:为何某些字符的 JavaScript 字符串长度并非恒定
2024-02-15 17:52:29
JavaScript 中的字符串编码是一个颇具吸引力的主题,特别是当我们发现某些字符的 length 属性并不是 1 时。要深入理解这一现象,我们不妨从 String.fromCharCode 和 String.fromCodePoint 这两个方法入手。
String.fromCharCode 与 String.fromCodePoint 的区别
String.fromCharCode 方法接受一系列 Unicode 码点作为参数,并返回一个由这些码点组成的字符串。例如:
console.log(String.fromCharCode(65)); // 输出:"A"
另一方面,String.fromCodePoint 方法也接受一系列 Unicode 码点作为参数,但它返回一个包含这些码点的字符串。与 String.fromCharCode 不同的是,String.fromCodePoint 可以处理补充字符(即大于 0xFFFF 的码点)。
console.log(String.fromCodePoint(0x1F603)); // 输出:"😃"
字符长度的奥秘
JavaScript 中的字符串长度由 length 属性确定,该属性返回字符串中字符的数量。然而,对于某些字符,其 length 属性并非恒定为 1。这是因为这些字符被编码为代理对,代理对由两个 16 位的 Unicode 码点组成。
代理对用于表示超出基本多语言平面的字符,该平面包含大多数常见字符。基本多语言平面使用 16 位的 Unicode 码点,但某些字符需要更多的位才能表示。
代理对的表示
代理对由两个 16 位的 Unicode 码点组成,称为高代理对和低代理对。高代理对的范围为 0xD800 至 0xDBFF,而低代理对的范围为 0xDC00 至 0xDFFF。
要形成代理对,需要将高代理对的码点左移 10 位,然后与低代理对的码点相加。结果是一个 21 位的码点,可以表示超出基本多语言平面的字符。
字符长度的影响
当一个字符串包含代理对时,其 length 属性将增加 2,而不是 1。这是因为代理对实际上由两个 16 位的 Unicode 码点组成。
例如,字符 "😃" 由一个代理对表示,高代理对为 0xD83D,低代理对为 0xDE03。因此,该字符的 length 属性为 2,而不是 1。
结论
JavaScript 中的字符串编码是一个复杂且引人入胜的主题。通过了解 String.fromCharCode 和 String.fromCodePoint 这两个方法,以及代理对的表示方式,我们可以理解为什么某些字符的 length 属性并非恒定为 1。掌握这些概念对于编写健壮且高效的 JavaScript 代码至关重要。