什么是默认的 JavaScript 字符编码

What is the default JavaScript character encoding?

本文关键字:字符 编码 JavaScript 默认 什么      更新时间:2023-09-26

在用JavaScript编写加密方法时,我开始想知道我的字符串使用了什么字符编码,以及为什么。

是什么决定了 JavaScript 中的字符编码?这是一个标准吗?通过浏览器?由 HTTP 请求的标头决定?在包含它的 HTML 的<META>标记中?为页面提供源的服务器?

通过我的经验测试(更改不同的设置,然后在足够奇怪的字符上使用charCodeAt并查看该值与哪个编码匹配),它似乎总是 UTF-8 或 UTF-16,但我不确定为什么

经过一番疯狂的谷歌搜索,我似乎找不到这个简单问题的决定性答案。

E262 的第 8.4 节:

String 类型是零个或多个 16 位无符号整数值("元素")的所有有限有序序列的集合。String 类型通常用于表示正在运行的 ECMAScript 程序中的文本数据,在这种情况下,String 中的每个元素都被视为一个代码单元值(参见条款 6)。每个元素都被视为在序列中占据一个位置。这些位置使用非负整数进行索引。第一个元素(如果有)位于位置 0,下一个元素(如果有)位于位置 1,依此类推。字符串的长度是其中元素(即 16 位值)的数量。空字符串的长度为零,因此不包含任何元素。

当字符串包含实际文本数据时,每个元素都被视为单个 UTF-16 代码单元。无论这是否是字符串的实际存储格式,字符串中的字符都按其初始代码单元元素位置进行编号,就像使用 UTF-16 表示一样。对字符串的所有操作(除非另有说明)将它们视为未区分的 16 位无符号整数序列;它们不确保生成的字符串采用规范化形式,也不确保对语言敏感的结果。

这种措辞有点令人讨厌;它似乎意味着所有计数都将字符串视为每个字符都是 UTF-16 字符,但同时没有什么可以确保它都是有效的。

需要明确的是,目的是字符串由 UTF-16 码位组成。在ES2015中,"字符串值"的定义包括以下注释:

字符串

值是字符串类型的成员。序列中的每个整数值通常表示 UTF-16 文本的单个 16 位单元。但是,ECMAScript 没有对值施加任何限制或要求,除了它们必须是 16 位无符号整数。

因此,即使字符串包含的值不能用作正确的 Unicode 字符,它仍然是字符串。

JavaScript 本身没有默认的字符编码。就规范而言,JavaScript程序是抽象字符的序列。当通过网络传输或仅存储在计算机中时,抽象字符必须以某种方式进行编码,但其机制不受 ECMAScript 标准的控制。

ECMAScript 标准的第 6 节使用 UTF-16 作为引用编码,但没有将其指定为缺省编码。使用 UTF−16 作为参考在逻辑上是不必要的(引用 Unicode 数字就足够了),但可能被认为可以帮助人们。

此问题不应与字符串文字或一般字符串的解释混淆。像"Φ"这样的文字需要与程序的其余部分一起采用某种编码;这可以是任何编码,但在解析编码后,文本将根据字符的 Unicode 编号解释为整数。

当 JavaScript 程序通过互联网传输(作为"外部 JavaScript 文件")时,RFC 4329 脚本媒体类型适用。第 4 条定义了机制:首先,检查诸如 HTTP 标头之类的标头,并且将信任那里的charset参数。(实际上,Web 服务器通常不会为 JavaScript 程序指定这样的参数。其次,应用物料清单检测。如果做不到这一点,则隐含 UTF-8。

该机制的第一部分有些模棱两可。它可能被解释为仅与实际 HTTP 标头中的charset参数相关,或者可能扩展到script元素中的charset参数。

如果一个JavaScript程序通过script元素或某个事件属性显示为嵌入在HTML中,那么它的字符编码当然与HTML文档的字符编码相同。指定 HTML 4.01 规范的字符编码部分按以下顺序定义了解析机制:charset HTTP 标头中,charset meta 中,charset访问文档的链接中,最后是启发式(猜测),这可能涉及很多事情;参见HTML5草案中的复杂解析机制。