在前端开发中,我们经常需要处理二进制数据。而 ArrayBuffer 和 TypedArray 就是 JavaScript 中的两个重要的二进制类型。 ArrayBuffer 是一个表示一个通用的、固定长度的二进制数据缓冲区,而 TypedArray 则是一个表示一个特定的二进制数据类型的视图(view)。它们在网络传输、图像处理、数据加密等领域得到了广泛应用。
然而,随着应用场景的增加,越来越多的需求被提出,导致了 ArrayBuffer 和 TypedArray 也出现了许多问题。
ArrayBuffer 的问题
ArrayBuffer 表示二进制数据缓冲区,但是这种缓冲区中的数据并没有指定字节顺序,这在不同的系统下可能会导致问题。例如,在一个小端字节序的系统中,数据被存储为最低有效字节的序列。而在大端字节序的系统中,数据被存储为最高有效字节的序列。这就导致了在不同的系统之间传输 ArrayBuffer 时需要进行字节序的转换,这非常麻烦。
另外,对 ArrayBuffer 的编码和解码也存在问题。目前,JavaScript 中的 ArrayBuffer 只支持将 UTF-16 编码的字符串转换为二进制数据并存储到 ArrayBuffer 中。这意味着如果需要将文本转换为二进制数据,需要使用一些非标准的方法,这增加了代码的复杂性。
TypedArray 的问题
TypedArray 是在 ArrayBuffer 基础上构建的,用于表示特定类型的二进制数据。它定义了一种数据类型和一种内存布局,用于向 ArrayBuffer 写入和读取数据。
但是,TypedArray 不能很好地处理字节序问题。考虑使用 Int16Array 读取一个字节序为小端的 ArrayBuffer 中的数据时,如果当前系统字节序为大端,就会读取到错误的值。
此外,TypedArray 的编码和解码问题也与 ArrayBuffer 相同。目前,只有一些内置的 TypedArray 才提供了将 UTF-8 编码的字符串转换为二进制数据的方法。对于其他的类型,仍需要使用非标准的方法。
解决方案
为了解决 ArrayBuffer 和 TypedArray 的上述问题,ECMAScript 2019 引入了一些新特性。
DataView
DataView 是一个可以读写 ArrayBuffer 的视图,与 TypedArray 不同的是,它可以明确指定字节序。可以使用如下语法创建 DataView:
const dataView = new DataView(buffer, byteOffset, byteLength);
其中,buffer 是一个 ArrayBuffer 实例;byteOffset 和 byteLength 则分别表示相对于 ArrayBuffer 的偏移量和数据长度。
创建 DataView 后,可以使用 get 和 set 方法读取和写入数据。这些方法会自动处理字节序问题,不需要手动转换。
例如,可以使用以下代码将一个大端序的 Int16 值写入 ArrayBuffer:
const buffer = new ArrayBuffer(2); const view = new DataView(buffer); view.setInt16(0, 1000, false);
其中,第三个参数表示是否按照小端序存储。
TextEncoder 和 TextDecoder
ECMAScript 2019 还引入了 TextEncoder 和 TextDecoder 两个新特性,用于将文本转换为二进制数据和将二进制数据转换为文本。
TextEncoder 是一个可以将 UTF-8、UTF-16 和 UTF-32 编码的字符串转换为 ArrayBuffer 的对象。使用如下语法创建 TextEncoder:
const encoder = new TextEncoder();
然后,可以使用 encode 方法将字符串转换为 ArrayBuffer:
const str = 'Hello'; const arrayBuffer = encoder.encode(str);
TextDecoder 是一个可以将 ArrayBuffer 转换为 UTF-8、UTF-16 和 UTF-32 编码的字符串的对象。使用如下语法创建 TextDecoder:
const decoder = new TextDecoder();
然后,可以使用 decode 方法将 ArrayBuffer 转换为字符串:
const str = decoder.decode(arrayBuffer);
由于 TextEncoder 和 TextDecoder 均是标准类型,因此可以在任何支持 ECMAScript 2019 的浏览器或 Node.js 环境中使用它们。
示例代码
以下是一个示例代码,演示了如何使用 DataView、TextEncoder 和 TextDecoder:
-- -------------------- ---- ------- -- -------- ---------- ----- --- - --- -------------- ------ - -- ------ - -- ------ - -- ------ - -- -- - ---------- --- ----------- ----- ------ - ----------- -- -- -------- ---- ----- ---- - --- ----------------- ------------------------------ -- - ------------------------------ -- - -- -- ----------- ----------- ----- ------- - --- -------------- ----- --- - -------- ----- ----------- - -------------------- -- -- ----------- ----------- ----- ------- - --- -------------- ----- ------ - ---------------------------- -------------------- -- -----
总结
ECMAScript 2019 引入了 DataView、TextEncoder 和 TextDecoder 三个新特性,用于解决 ArrayBuffer 和 TypedArray 中存在的编码和字节序问题。这些新特性为前端开发者提供了更加方便、可靠的二进制数据处理方式,减少了代码的复杂度,并且可以在各种系统下实现良好的兼容性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f19469f6b2d6eab3b661d4