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

时间:2016-06-21 14:32:35

标签: javascript json arraybuffer typed-arrays

我正在尝试创建ArrayBuffer对象的视图以便JSONify它。

var data = { data: new Uint8Array(arrayBuffer) }
var json = JSON.stringify(data)

即使最小的ArrayBufferUint8Array的大小似乎也无关紧要。到目前为止我没有得到任何RangeError :)如果是这样,我该如何决定使用哪种类型的数组?

1 个答案:

答案 0 :(得分:3)

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

Uint8Array也不是8位数组,它是无符号8位整数数组。它可以有任何长度。从与Uint8Array相同的ArrayBuffer创建的Uint16Array将是两倍长,因为ArrayBuffer中的每个字节都将被放置" 34;作为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));

输出将是

10
1
100000010

因为显示为二进制的无符号8位整数,2为00000010,1为00000001.(toString剥离前导零。)

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

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

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

如果您将此数据解释为基数10(十进制)整数,则您将100000010知道基数为10(258)。

0000000100000010Uint8Array都不存储任何数据。它们只是在Uint16Array中访问字节的不同方式。

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