arr = new Int8Array([-1,-1],0); // gives [-1,-1]
str = new TextDecoder('utf-8').decode(arr); // gives "��"
res = new TextEncoder('utf-8').encode(str); // gives [239, 191, 189, 239, 191, 189] instead of [-1,-1]
它不适用于负值。完美地为正面工作。还有其他选择吗?
答案 0 :(得分:2)
第1部分:字节不是
TextDecoder接口对Int8Array视图包装的底层ArrayBuffer(字节序列)进行操作。
此:
new TextDecoder('utf-8').decode(new Int8Array([-1, -1]))
与:
相同new TextDecoder('utf-8').decode(new Int8Array([-1, -1]).buffer)
哪个是包含字节0xFF,0xFF的ArrayBuffer。所以它与:
相同new TextDecoder('utf-8').decode(new Uint8Array([255, 255]))
第2部分:UTF-8解码
0xFF不是UTF-8中的有效代码序列,因此它将解码为错误。这导致REPLACEMENT CHARACTER(U + FFFD)。由于有两个0xFF字节,因此可以得到U + FFFD U + FFFD或:
""
第3部分:UTF-8编码
将U + FFFD编码为UTF-8,为您提供字节0xEF 0xBF 0xBD。所以用U + FFFD U + FFFD编码一个字符串会得到字节0xEF 0xBF 0xBD或十进制:239 191 189 239 191 189
......这正是你得到的结果。
所以这完全符合规定。
那么......问题是什么?
我的猜测是你假设你可以将任何字节编码成字符串。这不是文本编码的工作方式。文本编码定义了从字符串元素到字节序列的映射。
并非所有编码都可以表示字符串的所有元素,但UTF-8(和UTF-16)可以表示JavaScript字符串中可能出现的所有代码点。
但反过来不是真的。并非所有字节序列都对应于字符。当发现无效字节序列时,会发生错误。默认情况下,TextDecoder API会生成替换字符(�U+ FFFD),但您可以使用fatal
标志来使其抛出异常。