Node.js对Unicode的支持如何?

11
根据其语言规范,JavaScript在Unicode方面存在一些问题(如果我理解正确的话),因为文本始终被处理为一个由16位组成的字符。 JavaScript: The Good Parts以类似的方式发表了看法。
当您搜索V8对UTF-8的支持时,会得到矛盾的说法。
那么:Node.js(当时提问时的当前版本是0.10.26)的Unicode支持状态如何?它能正确地处理所有可能的UTF-8代码点吗,还是不行?
如果不能:有哪些可能的解决方法?
2个回答

9
你引用的两个来源,即语言规范和Crockford的《JavaScript: The Good Parts》(第103页),说的是同一件事,尽管后者更加简洁明了(如果你已经知道这个主题的话)。为了参考,我将引用Crockford的话:

当Unicode预计最多只有65,536个字符时,JavaScript被设计出来。它现在已经发展到具有超过100万个字符的能力。

JavaScript的字符是16位的。这足以涵盖最初的65,536个字符(现在称为基本多语言平面)。其余的百万个字符可以表示为一对字符。Unicode认为这对字符是单个字符。JavaScript认为这对字符是两个不同的字符。

语言规范将16位单位称为“字符”和“代码单元”。另一方面,“Unicode字符”或“代码点”可能需要两个16位的“代码单元”来表示(在罕见的情况下)。

JavaScript的所有字符串属性和方法,如lengthsubstr()等,都使用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对此“正确”的解释,答案是“是”。

进一步阅读和思考: https://mathiasbynens.be/notes/javascript-unicode


0

JavaScript字符串类型是UTF-16,因此它的Unicode支持率为100%。所有UTF形式都支持所有Unicode代码点。

以下是常见形式的一般分解:

  • UTF-8 - 8位代码单元;可变宽度(代码点为1-4个代码单元)
  • UTF-16 - 16位代码单元;可变宽度(代码点为1-2个代码单元);大端或小端
  • UTF-32 - 32位代码单元;固定宽度;大端或小端

当认为每个代码点都适合16位时,UTF-16变得流行起来。但事实并非如此。后来重新设计了UTF-16以允许代码点占用两个代码单元,并将旧版本更名为UCS-2。

然而,显式宽度与内存存储单元并不相等,因此UTF-16和UTF-32的实用性有限。自然语言很复杂,在许多情况下,代码点序列以令人惊讶的方式组合。

“字符”的宽度测量取决于上下文。内存?可见字形数量?以像素为单位的渲染宽度?

UTF-16仍然广泛使用,因为今天流行的许多语言/环境(Java / JavaScript / Windows NT)都诞生于90年代。它没有问题。但是,通常更喜欢使用UTF-8。

如果您遇到数据丢失/损坏问题,通常是由于转码器存在缺陷或错误使用转码器造成的。


但是,UTF-16与每个字符使用16位完全不同:UTF-16动态使用16或32位,而JavaScript据我所知静态使用16位。因此:在我看来,JavaScript不使用UTF-16,我提供的所有链接也都是这样说的。你有任何更新的来源吗? - Golo Roden
1
JavaScript中字符串的长度是代码__单元__的数量(每个单元在UTF-16中为16位)。一个代码__点__(如果您喜欢,可以是Unicode字符)在UTF-16中可以是一个或两个代码__单元__。因此,在JavaScript中,单个代码__点__的长度可以为2。这就是UTF-16的工作原理。JavaScript支持UTF-16,如ECMA 262第4.3.16节所述。我认为您引用的作者批评的是UTF-16而不是JavaScript的UTF-16一致性。这也是C#和Java中字符串的工作方式。 - McDowell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接