我正在尝试创建ArrayBuffer
对象的视图以便JSONify它。
var data = { data: new Uint8Array(arrayBuffer) }
var json = JSON.stringify(data)
即使最小的ArrayBuffer
,Uint8Array
的大小似乎也无关紧要。到目前为止我没有得到任何RangeError :)如果是这样,我该如何决定使用哪种类型的数组?
答案 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)。
0000000100000010
和Uint8Array
都不存储任何数据。它们只是在Uint16Array
中访问字节的不同方式。
如何选择使用哪一个?它不是基于偏好而是基于底层数据。当您从某个外部源(可能是Web套接字)接收到某些二进制数据并且已经知道数据所代表的内容时,将使用ArrayBuffer
。它可能是无符号8位整数列表,也可能是有符号16位整数的列表,甚至是混合列表,其中您知道第一个元素是8位整数,下一个是16位整数。然后,您可以使用ArrayBuffer
从中读取输入的项目。
如果您不知道数据代表什么,则无法选择要使用的内容。