【问题标题】:How well is Node.js' support for Unicode?Node.js 对 Unicode 的支持如何?
【发布时间】:2014-04-27 21:51:53
【问题描述】:

根据其language specification,JavaScript 在 Unicode 方面存在一些问题(如果我理解正确的话),因为文本始终在内部被处理为一个由 16 位组成的字符。

JavaScript: The Good Parts 以类似的方式表达出来。

当您在 Google 上搜索 V8 对 UTF-8 的支持时,您会得到相互矛盾的陈述。

那么:Node.js 中 Unicode 支持的状态是什么(当被问到这个问题时,当前版本是 0.10.26)?它是否正确处理 UTF-8 将所有可能的代码点,或者不是吗?

如果不是:有哪些可能的解决方法?

【问题讨论】:

    标签: javascript node.js unicode v8


    【解决方案1】:

    JavaScript 字符串类型为 UTF-16,因此其 Unicode 支持率为 100%。 所有UTF 表单都支持所有Unicode 代码点。

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

    • UTF-8 - 8 位代码单元;可变宽度(代码点为 1-4 个代码单元)
    • UTF-16 - 16 位代码单元;可变宽度(代码点为 1-2 个代码单元); big-endian 或 little-endian
    • 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 AFAIK 静态使用 16 位。所以:恕我直言,JavaScript 不使用 UTF-16,我提供的所有链接也都如此。你有任何更新的来源吗?
    • JavaScript 中字符串的长度是代码units 的数量(在UTF-16 中每个单位都是16 位宽。)代码point(Unicode 字符,如果你喜欢的话)可以是 UTF-16 中的一个或两个代码 units。因此,单个代码 point 在 JavaScript 中的长度可以为 2。这就是 UTF-16 的工作原理。根据4.3.16 String value in ECMA 262 部分,JavaScript 支持 UTF-16。我认为您引用的作者是在批评 UTF-16 而不是 JavaScript 的 UTF-16 一致性。这也是字符串在 C# 和 Java 中的工作方式。
    【解决方案2】:

    您引用的两个来源,language specification 和 Crockford 的“JavaScript: The Good Parts”(第 103 页)说了同样的话,尽管后者说得更简洁(如果你已经知道这个主题,那么清楚) .作为参考,我将引用 Crockford:

    JavaScript 是在 Unicode 预计最多有 65,536 个字符的时候设计的。此后,它的容量已超过 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 对此“正确”的解释,则答案是“是”。

    【讨论】:

      猜你喜欢
      • 2011-07-15
      • 2013-06-10
      • 1970-01-01
      • 2012-08-07
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多