ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JS的定型数组

2022-06-22 20:00:46  阅读:130  来源: 互联网

标签:定型 缓冲 ArrayBuffer DataView 视图 alert 数组 JS buf


定型数组(typed array)是ECMAScript新增的结构,目的是提升向原生库传输数据的效率。实际上,JavaScript并没有”TypedArray“类型,它所指的其实是一种特殊的包含数值类型的数组。为理解如何使用定型数组,有必要先了解一下它的用途。

 

①ArrayBuffer

  Float32Array实际上是一种”视图“,可以允许JavaScript运行时访问一块名为ArrayBuffer的预分配内存。ArrayBuffer是所有定型数组及视图引用的基本单位。

注意:SharedArrayBuffer是ArrayBuffer的一个变体,可以无需复制就在执行上下文传递它。

 

ArrayBuffer()是一个普通的JavaScript构造函数,可用于在内存中分配特定数量的字节空间。

const buf=new ArrayBuffer(16);   //在内存中分配16字节
alert(buf.byteLength);    //16

ArrayBuffer一经创建就不能再调整大小,不过,可以使用slice()复制其全部或部分到一个新实例中:

const buf1=new ArrayBuffer(16);
const buf2=buf1.slice(4,12);
alert(buf2.byteLength);      //8

ArrayBuffer某种程度上类似于C++的malloc(),但也有几个明显的区别。

1)malloc()在分配失败时候会返回一个null指针。ArrayBuffer在分配失败时会抛出错误。

2)malloc()可以利用虚拟内存,因此最大可分配尺寸只受可寻址系统内存限制。ArrayBuffer分配的内存不能超过Number.Max_SAFE_INTEGER(2^53-1)字节

3)malloc()调用成功不会初始化实际的地址。声明ArrayBuffer,则会将所有二进制位初始化位0.

4)通过malloc()分配的堆内存除非调用free()或程序退出,否则系统不能再使用。而通过声明ArrayBuffer分配的堆内存可以被当成垃圾回收,不同手动释放。

不能仅通过对ArrayBuffer的引用就读取或写入其内容。要读取或写入ArrayBuffer,就必须通过视图。视图有不同的类型,但引用的都是ArrayBuffer中存储的二进制数据。

 

一、DataView

  第一种允许你读写ArrayBuffer的视图是DataView。这个视图专为文件I/O和网络I/O设计,其API支持对缓冲数据的高度控制,但相比于其他类型的视图性能也差一些。DataView对缓冲内容没有任何预设,也不能迭代。

  必须在对已有的ArrayBuffer读取或者写入时才能创建DataView实例。这个实例可以使用全部或者部分ArrayBuffer,且维护着对该缓冲实例的引用,以及视图在缓冲中开始的位置。

const buf=new ArrayBuffer(16);


//DataView默认使用整个ArrayBuffer
const fullDataView=new DataView(buf);
alert(fullDataView.byteOffset);   //0
alert(fullDataView.byteLength);  //16
alert(fullDataView.buffer===buf);       //true


//构造函数接收一个可选的字节偏移量和字节长度
//byteOffset=0表示视图从缓冲起点开始
//byteLength=8 限制视图为前8个字节

const firstHalfDataView=new DataView(buf,0,8);
alert(firstHalfDataView.byteOffset);     //0
alert(firstHalfDataView.byteLength);    //8
alert(firstHalfDataView.buffer===buf);   //true


//如果不指定,则DataView会使用剩余的缓冲
//byteOffset=8 表示视图从缓冲的第九个字节开始
// byteLength未指定,默认为剩余缓冲
const secondHalfDataView=new DataView(buf,8);
alert(secondHalfDataView.byteOffset);        //8
alert(secondHalfDataView.byteLength);        //8
alert(secondHalfDataView.buffer===buf);        //true
alert(secondHalfDataView.byteLength);        //8
alert(secondHalfDataView.buffer===buf); //true

要通过DataView读取缓冲,还需要几个组件。

首先是要读或写的字节偏移量。可以看成DataView中的某种”地址“。

DataView应该使用ElementType来实现JavaScript的Number类型到缓冲内二进制格式的转换。

最后是内存中值的字节序。默认为大端字节序。

(1)ElementType

DataView对存储在缓冲内的数据类型没有预设。它暴露的API强制开发者在读、写时指定一个ElementType,然后DataView就会忠实地为读、写而完成相应的转换。

ES6支持八种不同的ElementType(如下表)

ElementType 字节 说明 等价的C类型 值的范围
Int8 1 8位有符号整数 signed char -127~127
Uint8 1 8位无符号整数 unsigned char 0~255
Int16 2 16位有符号整数 short -32768~32767
Uint16 2 16位无符号整数 unsigned short 0~65535
Int32 4 32位有符号整数 int -2147483648~2147483647
Uint32 4 32位无符号整数 unsigned int 0~4294967295
Float32 4 32位IEEE-754浮点数 float -3.4e+38~+3.4e+38
Float 8 64位IEEE-754浮点数 double -1.7e+308~+1.7e+308

DataView为上表中的每种类型都暴露了get和set方法,这些方法使用byteOffset(字节偏移量)定位要读取或者写入值的位置。类型是可以互换使用的,如下例所示:

//在内存中分配两个字节并声明一个DataView

const buf=new ArrayBuffer(2);

const view=new DataView(buf);

 

//说明整个缓冲确实所有二进制位都是0

//检查第一个和第二个字符

alert(view.getInt8(0));  //0

alert(view.getInt8(1));  //0

//检查整个缓冲

alert(view.getInt(16));   //0

//将整个缓冲都设置为1

//255的二进制表示是11111111

view.setUint8(0,255);

//DataView会自动将数据转换为特定的ElementType

//255的十六进制表示为0xFF

view.setUint8(1,0xFF);

//现在、缓冲里都是1了

//如果把它当成二补数的有符号整数,则应该是-1

alert(view.getInt16(0));    //-1

标签:定型,缓冲,ArrayBuffer,DataView,视图,alert,数组,JS,buf
来源: https://www.cnblogs.com/jaetyn/p/16402105.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有