我一直在试图理解为什么对UTF-8进行编码/解码的需求在JavaScript领域中无处不在,并且了解到JavaScript使用UTF-16编码。
Let’s talk about Javascript string encoding
因此,我假设这就是存在诸如utf8.js之类的库以便在UTF-16和UTF-8之间进行转换的原因。
但是最后他提供了一些见解:
在Node中编码非常混乱,并且很难正确设置。但是,当您意识到Javascript字符串类型将始终被编码为UTF-16且在RAM中的其他大多数字符串与套接字,文件或字节数组进行交互时,它会有所帮助,该字符串将被重新编码为UTF-8
当然,这都是非常低效的。大多数字符串都可以表示为UTF-8,并且使用两个字节来表示它们的字符意味着您使用的内存超出了您的需要,并且每次遇到HTTP时都要支付O(n)税来重新编码字符串或文件系统边界。
这使我想起了HTML <head>
中的<meta charset=“utf-8”>
,除了“您需要使用它才能使文本正常工作”之外,我从来没有想过太多。
现在,我想知道,这个问题是关于那个<meta charset=“utf-8”>
标签是否告诉 JavaScript 进行UTF-8编码的。这意味着在JavaScript中创建字符串时,字符串将采用UTF-8编码,而不是UTF-16。或者,如果我错了,那到底是在做什么。如果它告诉JavaScript使用UTF-8编码而不是UTF-16(我认为这将是“默认”),那么这意味着您无需为此支付O(n)
税UTF-8和UTF-16之间的转换,这意味着性能上的提高。想知道我是否正确理解了,或者如果我没有正确理解我所缺少的。
答案 0 :(得分:1)
元字符集
<meta charset=“utf-8”>
标签告诉 HTML (不太严格:HTML解析器),页面的编码为utf8。
JS没有内置的功能可以在不同的字符串之间切换-它始终是utf-16。
渐近边界
我认为编码转换不会受到O(n)
的惩罚。每当需要进行这种编码更改时,就已经有O(n)
操作了 :读取/写入数据流。因此,每个八位位组上任何固定数量的操作仍为O(n)
。编码更改仅需要本地知识,即。仅固定长度的超前窗口,因此可以以O(1)
的代价并入流读/写代码中。
您可能会争辩说空间损失为O(n)
,尽管如果需要以任何标准编码来存储字符串(即,不压缩),则移至utf-16的系数为2最大值因此保持在O(n)
范围内。
恒定因素
即使关注是使隐藏在O(n)
表示法编码更改中的常数因子最小化,也至少在时域中具有适度的影响。对于大部分(西方)文本数据,以utf-8格式写入/读取utf-16流意味着跳过第二个八位位组/插入空八位位组。与与套接字或文件系统接口产生的开销和延迟相比,该性能下降了。
存储当然有所不同,尽管今天存储相对便宜,并且2的上限仍然成立。从32位转换为64位对数字表示和指针的内存影响更大。
答案 1 :(得分:1)
JavaScript 使用 UTF-16
HTML5 使用 UTF-8
您的元标记设置适用于 HTML5 编码,这是可选的,因为大多数现代浏览器都知道 HTML5 是 UTF-8。但是,它与 JavaScript 编码无关,并且不会更改或影响 JavaScript,只是告诉它使用 UTF-8 编码对您的页面进行解码。
大多数现代 Javascript 引擎的工作方式是,它们确实将 UTF-8 脚本、HTML 标记和页面文本读取和解码为 UTF-16。但是出于速度和其他原因,它们通常以其本机形式存储第一个 ASCII 集(英文字符和数字),或者像 UTF-8 或您的网页那样存储为一个字节。这不是硬性规定。因此,在 Chrome 的 V8 javascript 引擎中由 Javascript 读取和存储的 HTML 标签可能仍将它们存储在一个字节中,而不是 UTF-16。
就以 UTF-8 存储的大多数 ASCII 字符而言,这些脚本引擎的幕后发生的事情不是您应该担心的。只有在流式传输更复杂的 Unicode 字符上层“平面”时才会遇到问题。 Javascript 存储和编码的 UTF-16 特性是可变的,我已经阅读过。在我看来,大多数 Web 开发人员不需要担心,直到您进入高级 Unicode 语言和 Javascript 中的字符集操作。这就是 Node 和许多开源引擎在解码和编码 UTF-8 和 UTF-16 方面遇到的困难,因为它们依赖于 Javascripting 引擎。
同样,因为现在一切都在朝着 UTF-8 编码发展(其中 1-4 个字节可选地用于编码完整的 Unicode 字符集,而 UTF-16 从 2 个字节集开始并上升)您将看到 Javascript处理所有将 UTF-8 解码为 UTF-16 的过程,然后作为一个非常无缝的过程返回,并有很多意外情况。
顺便说一句......脚本引擎读取或找出以UTF-8编码的Javascript文件的方式,是Javascript首先侦听来自服务器的HTTP标头中的mime类型或“内容类型”和字符集看看所有的网页文件应该从什么解码。如前所述,现在在 HTML5 中几乎总是 UTF-8。如果它无法确定类型,它接下来会检查您的脚本的 <script>
标记及其自定义类型属性的 mime 类型和/或字符集,以查看您的 javascript 源文件是否设置了该类型。在大多数情况下,这些都缺失了。最后,它检查网页元标记字符集,该字符集是 UTF-8,或者如果使用 HTML5,则它假定为 UTF-8。脚本文件上还有可能是 UTF-8 的“字节顺序标记”。即使它是用 ASCII 编码的,或者说直接转换为 UTF-8 的 Latin-1,无论如何。一旦知道编码,Javascript 就会解码这些位并将它们编码成自己的 2 字节集,如上所述。
在一天结束时,引擎会为您完成所有这些谈判。