我正在尝试创建 ArrayBuffer
对象的 View 以便对其进行 JSONify。
var data = { data: new Uint8Array(arrayBuffer) }
var json = JSON.stringify(data)
即使使用最小的 Uint8Array
,ArrayBuffer
的大小似乎也并不重要。到目前为止我还没有收到任何 RangeError:) 如果是这样,我如何决定使用哪个类型数组?
最佳答案
您根据缓冲区中存储的数据做出决定,或者更好地说,根据您对该数据的解释。
此外,Uint8Array
不是一个 8 位数组,它是一个无符号 8 位整数数组。它可以有任意长度。从与 Uint16Array
相同的 ArrayBuffer
创建的 Uint8Array
的长度将是 Uint16Array
的两倍,因为 ArrayBuffer
中的每个字节code> 将被“放置”为 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 位整数(两个字节),因此当您访问 uint16View 时[0]
它将获取前两个字节并将它们返回给您。因此 0000000100000010
,即 100000010
,没有前导零。
如果您将此数据解释为以 10 为基数(十进制)的整数,您就会知道它是 0000000100000010
到以 10 为基数 (258)。
Uint8Array
和 Uint16Array
本身都不存储任何数据。它们只是访问 ArrayBuffer 中字节的不同方式。
如何选择使用哪一个?它不是基于偏好,而是基于基础数据。当您从某些外部源(可能是网络套接字)接收一些二进制数据并且已经知道数据代表什么时,将使用ArrayBuffer
。它可能是一个无符号 8 位整数列表,或者一个有符号 16 位整数,甚至是一个混合列表,其中您知道第一个元素是 8 位整数,下一个元素是 16 位整数。然后您可以使用 DataView 从中读取键入的项目。
如果您不知道数据代表什么,您就无法选择使用什么。
关于javascript - 如何决定使用哪种类型数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37947300/