为什么JavaScript字符串采用UTF-16编码但单字符实际大小可仅为1字节?
问题本质
你观察到的差异来自两个独立场景下的编码规则区别,核心是没有区分JavaScript字符串的规范定义逻辑,和Blob接口的序列化编码规则:
- JavaScript语言规范明确约定,字符串类型的所有对外操作逻辑,都基于UTF-16码元序列实现:比如字符串
length计数、下标取值、正则匹配等行为,都严格遵循UTF-16码元的计算规则——比如需要两个UTF-16码元表示的emoji😀,调用'😀'.length会返回2,和你查阅的资料描述完全一致。注意规范只约束对外的行为表现,并不强制引擎底层必须用UTF-16格式存储字符串,现代V8等引擎对全ASCII字符的字符串,会自动用单字节格式存储做内存优化,只是对外行为保持符合规范即可。 - 当你向Blob构造函数传入字符串时,Blob不会直接读取JS引擎内部的字符串原始存储,而是会按照Web标准对内容做转码序列化:没有显式指定编码的前提下,Blob默认采用UTF-8编码处理字符串内容。英文字母
a属于ASCII范畴字符,在UTF-8规则下本身仅占1字节,因此new Blob(['a']).size === 1是完全符合标准的预期结果,和JS内部的字符串处理逻辑没有绑定关系。
验证方法
你可以通过非ASCII字符的测试直观验证规则:
- 执行
new Blob(['中']).size会返回3,对应常用汉字在UTF-8下的3字节长度; - 执行
new Blob(['😀']).size会返回4,对应该emoji在UTF-8下的4字节长度;
上述结果和UTF-16编码下的字符长度完全不匹配,可以直接证明Blob的大小计算和JS内部的UTF-16字符串逻辑无关。
内容的提问来源于stack exchange,提问作者Joji
相关产品推荐
相关产品推荐

