当您搜索V8对UTF-8的支持时,会得到矛盾的说法。
那么:Node.js(当时提问时的当前版本是0.10.26)的Unicode支持状态如何?它能正确地处理所有可能的UTF-8代码点吗,还是不行?
如果不能:有哪些可能的解决方法?
当Unicode预计最多只有65,536个字符时,JavaScript被设计出来。它现在已经发展到具有超过100万个字符的能力。
JavaScript的字符是16位的。这足以涵盖最初的65,536个字符(现在称为基本多语言平面)。其余的百万个字符可以表示为一对字符。Unicode认为这对字符是单个字符。JavaScript认为这对字符是两个不同的字符。
语言规范将16位单位称为“字符”和“代码单元”。另一方面,“Unicode字符”或“代码点”可能需要两个16位的“代码单元”来表示(在罕见的情况下)。
JavaScript的所有字符串属性和方法,如length
、substr()
等,都使用16位“字符”(使用16位/32位Unicode字符,即UTF-16字符,会非常低效)。例如,这意味着,如果你不小心,在使用substr()
时,你可能会忽略32位UTF-16 Unicode字符的一半。只要你不显示它,JavaScript就不会抱怨,甚至在你显示它时也可能不会抱怨。这是因为,正如规范所说,JavaScript不会检查字符是否是有效的UTF-16,它只假定它们是。
在你的问题中,你问道:
[Node.js]是否正确处理了所有可能的UTF-8代码点?
由于在任何其他操作之前,所有可能的UTF-8代码点都会被转换为UTF-16(作为一个或两个16位“字符”)的输入,反之亦然的输出,答案取决于你对“正确”的理解,但如果你接受JavaScript对此“正确”的解释,答案是“是”。
JavaScript字符串类型是UTF-16,因此它的Unicode支持率为100%。所有UTF形式都支持所有Unicode代码点。
以下是常见形式的一般分解:
当认为每个代码点都适合16位时,UTF-16变得流行起来。但事实并非如此。后来重新设计了UTF-16以允许代码点占用两个代码单元,并将旧版本更名为UCS-2。
然而,显式宽度与内存存储单元并不相等,因此UTF-16和UTF-32的实用性有限。自然语言很复杂,在许多情况下,代码点序列以令人惊讶的方式组合。
“字符”的宽度测量取决于上下文。内存?可见字形数量?以像素为单位的渲染宽度?
UTF-16仍然广泛使用,因为今天流行的许多语言/环境(Java / JavaScript / Windows NT)都诞生于90年代。它没有问题。但是,通常更喜欢使用UTF-8。
如果您遇到数据丢失/损坏问题,通常是由于转码器存在缺陷或错误使用转码器造成的。