如何决定使用哪种类型数组?

saw*_*awa 0 javascript json typed-arrays arraybuffer

我正在尝试创建对象视图ArrayBuffer以便对其进行 JSONify。

var data = { data: new Uint8Array(arrayBuffer) }
var json = JSON.stringify(data)
Run Code Online (Sandbox Code Playgroud)

看起来,即使是最小的,大小ArrayBuffer也并不重要Uint8Array。到目前为止我没有收到任何 RangeError:) 如果是这样,我如何决定使用哪个类型数组?

Ser*_*hiv 5

您根据缓冲区中存储的数据做出决定,或者更好地说,根据您对该数据的解释做出决定。

另外 anUint8Array不是 8 位数组,它是无符号 8 位整数的数组。它可以有任意长度。Uint8Array由与ArrayBuffera相同创建的A 的Uint16Array长度将是 a 的两倍,因为 a 中的每个字节ArrayBuffer都将被“放置”为 的一个元素Uint8Array,而Uint16Array每对字节将“成为”中的一个元素大批。

对所发生情况的一个很好的解释是,如果我们尝试用二进制思维。尝试运行这个:

var buffer = new ArrayBuffer(2);
var uint8View = new Uint8Array(buffer);
var uint16View = new Uint16Array(buffer);

uint8View[0] = 2;
uint8View[1] = 1;

console.log(uint8View[0].toString(2));
console.log(uint8View[1].toString(2));
console.log(uint16View[0].toString(2));
Run Code Online (Sandbox Code Playgroud)

输出将是

10
1
100000010
Run Code Online (Sandbox Code Playgroud)

因为以二进制形式显示为无符号 8 位整数,所以 2 是 00000010,1 是 00000001。(toString去掉前导零)。

Uint8Array表示一个字节数组。正如我所说,元素是一个无符号 8 位整数。我们只是向它推送了两个字节。

在内存中,这两个字节并排存储为 00000001 00000010(再次使用二进制形式使事情更清晰)。

现在,当您在Uint16Array同一缓冲区上初始化 a 时,它将包含相同的字节,但由于元素是无符号 16 位整数(两个字节),因此当您访问时,uint16View[0]它将获取前两个字节并将它们返回给您。所以0000000100000010,它100000010没有前导零。

如果您将此数据解释为以 10 为底的(十进制)整数,您就会知道它0000000100000010以 10 为底 (258)。

Uint8Array本身也不存储Uint16Array任何数据。它们只是访问ArrayBuffer.

如何选择使用哪一个?它不是基于偏好,而是基于基础数据。当您从某些外部源(可能是 Web 套接字)接收一些二进制数据并且已经知道数据代表什么时,ArrayBuffer将使用它。它可能是一个无符号 8 位整数列表,或者一个有符号 16 位整数,甚至是一个混合列表,其中您知道第一个元素是 8 位整数,下一个元素是 16 位整数。然后您可以使用它来读取键入的项目。如果您不知道数据代表什么,您就无法选择使用什么。DataView