Javascript 类型数组

front end technologyjavascriptobject oriented programming

JavaScript 数组是用于解决不同问题的最基本的数据结构之一。大多数不同的编程语言都提供数组功能,以连续保存类似类型的数据元素。Web 编程语言 JavaScript 也允许在其中使用数组。JavaScript 还支持另一个有趣的功能,称为类型数组。类型数组与普通数组类似,但它提供在内存缓冲区中读取和写入原始二进制数据的功能。

为什么我们需要类型数组?

与其他编程语言一样,JavaScript 支持数组对象,可以在其中存储值和对象。这些数组是动态的,因此它们可以在需要时增长和缩小。对于 Web 编程,JavaScript 优化了源代码,引擎执行数组访问的速度更快。但在普通数组中,它可以存储任何类型的数据,而在 Web 技术中,数据变化更加灵活。有时它们可​​以是图像、视频音频和其他一些对象类型。但有时我们可能需要直接从内存访问原始二进制数据。在这方面,类型化数组应运而生。JavaScript 类型化数组中的每个元素都是原始二进制数据。支持多种不同的数据格式。从 8 位整数到 64 位浮点数等等。

类型化数组的组件:缓冲区和视图

JavaScript 中的类型化数组有一些组件,可以完全灵活地使用类型化数组功能。它主要有两个不同的组件。第一个是缓冲区,第二个是视图。缓冲区可以使用 JavaScript 中的 ArrayBuffer 对象实现。此对象表示数据块。要读取、写入和操作数据,我们需要使用视图。视图就像一个窗口。从不同大小的视图(如不同大小的窗口)中,我们可以看到 ArrayBuffer 中不同大小的字节组件。此视图提供了一个上下文,其中可以使用数据类型、起始偏移量、索引管理和元素数量。因此,可以形成整个类似数组的对象。请参见下图以了解 ArrayBuffer 的概念及其不同视图。

JavaScript 中的 ArrayBuffer

ArrayBuffer 数据类型创建一个通用的固定长度二进制数据缓冲区。要创建 ArrayBuffer,我们需要提供要分配的字节数。语法相当简单 −

语法

buffer = new ArrayBuffer(<number of bytes>)

JavaScript 中的 DataView

DataView 可以完全控制 JavaScript 中的类型化数组。有几种类型的视图,例如 Int8Array− 用于 8 位有符号整数。 Uint8Array− 用于 8 位无符号数。 Float64Array− 用于 64 位 IEEE 浮点数等。这些 DataView 提供了一个低级接口,使 getter/setter API 能够读取和写入任意数据到 ArrayBuffer。创建视图也很简单。遵循语法以便更好地理解−

语法

view1 = new ViewType(<array buffer object>);
view2 = new ViewType(<array buffer object>);

ViewType 可以是任何类型,例如 Float64Array、Int32Array 等。

示例

定义一个大小为 16 字节的简单 ArrayBuffer,并打印其大小。

源代码

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3>Output Console</h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const buffer = new ArrayBuffer(16); content += "Size of buffer: " + buffer.byteLength } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

创建一个 Int32Array 视图来存储 32 位整数。并在其中存储前几个平方数

源代码

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const buffer = new ArrayBuffer(16); const int32View = new Int32Array(buffer); for (let i = 0; i < int32View.length; i++) { int32View[i] = i * i; } content += "The int32View Buffer: " + int32View } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

为什么只生成了四个整数?这是因为我们创建了一个 32 位整数数组,因此每个整数占用 32 位空间(4 个字节)。而我们的缓冲区是 16 个字节。因此生成了 16/4 = 4 个整数。

我们可以对同一个 ArrayBuffer 使用多个视图。在下面的示例中,我们为同一个数组缓冲区创建了另一个 16 位整数视图。

源代码

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const buffer = new ArrayBuffer(16); const int32View = new Int32Array(buffer); const int16View = new Int16Array(buffer); for (let i = 0; i < int32View.length; i++) { int32View[i] = i * i; } content += "The int32View Buffer: " + int32View + '<br>' content += "The int16View Buffer: " + int16View + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

输出显示,对于 16 位整数,它为同一个缓冲区创建了 8 个数字。但我们可以看到,中间有些数字是 0。这背后的原因很简单。例如,Int32Array 中的数字 9 本身就是 9,但在 Int16Array 中它变成了 (0, 9),这是因为在第一种情况下,9 表示为 32 位数字,其中最低有效 4 位表示 9 (1001)。但在下一种情况下,这 32 位被分成两个 16 位数字,最高有效 16 位现在是不同的数字。在这种情况下,它变成了 0

我们可以对同一个 ArrayBuffer 使用多个视图。在以下示例中,我们为同一数组缓冲区创建另一个 16 位整数视图。在下一个示例中,我们可以看到,如果我们从一个视图更新类型数组中存在的元素的值,那么从另一个视图来看,它也将得到更新。

源代码

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const buffer = new ArrayBuffer(16); const int32View = new Int32Array(buffer); const int16View = new Int16Array(buffer); for (let i = 0; i < int32View.length; i++) { int32View[i] = i * i; } content += 'Before<br>' content += "The int32View Buffer: " + int32View + '<br>' content += "The int16View Buffer: " + int16View + '<br>' int16View[0] = 50; content += '<br>After<br>' content += "The int32View Buffer: " + int32View + '<br>' content += "The int16View Buffer: " + int16View + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

结论

类型化数组与 JavaScript 中的普通数组对象非常相似。通过这种方法,我们可以直接从内存中访问原始二进制数据。类型化数组概念中存在两个不同的组件。第一个是给定大小(以字节为单位)的实际缓冲区对象,第二个是视图。单个缓冲区可能有多个视图。这些视图具有不同的数据类型、大小和其他与之相关的参数,使缓冲区用作普通数组对象。


相关文章