您如何决定使用哪种类型化数组?
How do you decide which typed array to use?
我正在尝试创建 ArrayBuffer
对象的视图以便对其进行 JSON 化。
var data = { data: new Uint8Array(arrayBuffer) }
var json = JSON.stringify(data)
似乎 ArrayBuffer
的大小与最小的 Uint8Array
无关。到目前为止我没有得到任何 RangeError :) 如果是这样,我如何决定使用哪个类型化数组?
您根据存储在缓冲区中的数据来决定,或者更好地说,根据您对该数据的解释来决定。
此外,Uint8Array
不是一个 8 位数组,它是一个无符号 8 位整数数组。它可以有任何长度。从与 Uint16Array
相同的 ArrayBuffer
创建的 Uint8Array
将是两倍长,因为 ArrayBuffer
中的每个字节都将是 "placed" Uint8Array
的一个元素,而 Uint16Array
每对字节将 "become" 数组中的一个元素。
一个很好的解释是如果我们尝试用二进制来思考会发生什么。尝试 运行 这个:
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
从中读取键入的项目。
如果您不知道数据代表什么,您就无法选择使用什么。
我正在尝试创建 ArrayBuffer
对象的视图以便对其进行 JSON 化。
var data = { data: new Uint8Array(arrayBuffer) }
var json = JSON.stringify(data)
似乎 ArrayBuffer
的大小与最小的 Uint8Array
无关。到目前为止我没有得到任何 RangeError :) 如果是这样,我如何决定使用哪个类型化数组?
您根据存储在缓冲区中的数据来决定,或者更好地说,根据您对该数据的解释来决定。
此外,Uint8Array
不是一个 8 位数组,它是一个无符号 8 位整数数组。它可以有任何长度。从与 Uint16Array
相同的 ArrayBuffer
创建的 Uint8Array
将是两倍长,因为 ArrayBuffer
中的每个字节都将是 "placed" Uint8Array
的一个元素,而 Uint16Array
每对字节将 "become" 数组中的一个元素。
一个很好的解释是如果我们尝试用二进制来思考会发生什么。尝试 运行 这个:
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
从中读取键入的项目。
如果您不知道数据代表什么,您就无法选择使用什么。