当前位置:K88软件开发文章中心编程语言JavaScriptECMAScript → 文章内容

ECMAScript 6 二进制数组

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:38:33

由 youj 创建, 最后一次修改 2016-09-20 ArrayBuffer对象TypedArray视图复合视图DataView视图二进制数组的应用二进制数组(ArrayBuffer对象、TypedArray视图和DataView视图)是JavaScript操作二进制数据的一个接口。这些对象早就存在,属于独立的规格(2011年2月发布),ES6将它们纳入了ECMAScript规格,并且增加了新的方法。这个接口的原始设计目的,与WebGL项目有关。所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个32位整数,两端的JavaScript脚本与显卡都要进行格式转化,将非常耗时。这时要是存在一种机制,可以像C语言那样,直接操作字节,将4个字节的32位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。二进制数组就是在这种背景下诞生的。它很像C语言的数组,允许开发者以数组下标的形式,直接操作内存,大大增强了JavaScript处理二进制数据的能力,使得开发者有可能通过JavaScript与操作系统的原生接口进行二进制通信。二进制数组由三类对象组成。(1)ArrayBuffer对象:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。(2)TypedArray视图:共包括9种类型的视图,比如Uint8Array(无符号8位整数)数组视图, Int16Array(16位整数)数组视图, Float32Array(32位浮点数)数组视图等等。(3)DataView视图:可以自定义复合格式的视图,比如第一个字节是Uint8(无符号8位整数)、第二、三个字节是Int16(16位整数)、第四个字节开始是Float32(32位浮点数)等等,此外还可以自定义字节序。简单说,ArrayBuffer对象代表原始的二进制数据,TypedArray视图用来读写简单类型的二进制数据,DataView视图用来读写复杂类型的二进制数据。TypedArray视图支持的数据类型一共有9种(DataView视图支持除Uint8C以外的其他8种)。数据类型字节长度含义对应的C语言类型Int818位带符号整数signed charUint818位不带符号整数unsigned charUint8C18位不带符号整数(自动过滤溢出)unsigned charInt16216位带符号整数shortUint16216位不带符号整数unsigned shortInt32432位带符号整数intUint32432位不带符号的整数unsigned intFloat32432位浮点数floatFloat64864位浮点数double注意,二进制数组并不是真正的数组,而是类似数组的对象。很多浏览器操作的API,用到了二进制数组操作二进制数据,下面是其中的几个。File APIXMLHttpRequestFetch APICanvasWebSocketsArrayBuffer对象概述ArrayBuffer对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写,视图的作用是以指定格式解读二进制数据。ArrayBuffer也是一个构造函数,可以分配一段可以存放数据的连续内存区域。var buf = new ArrayBuffer(32);上面代码生成了一段32字节的内存区域,每个字节的值默认都是0。可以看到,ArrayBuffer构造函数的参数是所需要的内存大小(单位字节)。为了读写这段内容,需要为它指定视图。DataView视图的创建,需要提供ArrayBuffer对象实例作为参数。var buf = new ArrayBuffer(32);var dataView = new DataView(buf);dataView.getUint8(0) // 0上面代码对一段32字节的内存,建立DataView视图,然后以不带符号的8位整数格式,读取第一个元素,结果得到0,因为原始内存的ArrayBuffer对象,默认所有位都是0。另一种TypedArray视图,与DataView视图的一个区别是,它不是一个构造函数,而是一组构造函数,代表不同的数据格式。var buffer = new ArrayBuffer(12);var x1 = new Int32Array(buffer);x1[0] = 1;var x2 = new Uint8Array(buffer);x2[0] = 2;x1[0] // 2上面代码对同一段内存,分别建立两种视图:32位带符号整数(Int32Array构造函数)和8位不带符号整数(Uint8Array构造函数)。由于两个视图对应的是同一段内存,一个视图修改底层内存,会影响到另一个视图。TypedArray视图的构造函数,除了接受ArrayBuffer实例作为参数,还可以接受普通数组作为参数,直接分配内存生成底层的ArrayBuffer实例,并同时完成对这段内存的赋值。var typedArray = new Uint8Array([0,1,2]);typedArray.length // 3typedArray[0] = 5;typedArray // [5, 1, 2]上面代码使用TypedArray视图的Uint8Array构造函数,新建一个不带符号的8位整数视图。可以看到,Uint8Array直接使用普通数组作为参数,对底层内存的赋值同时完成。ArrayBuffer.prototype.byteLengthArrayBuffer实例的byteLength属性,返回所分配的内存区域的字节长度。var buffer = new ArrayBuffer(32);buffer.byteLength// 32如果要分配的内存区域很大,有可能分配失败(因为没有那么多的连续空余内存),所以有必要检查是否分配成功。if (buffer.byteLength === n) { // 成功} else { // 失败}ArrayBuffer.prototype.slice()ArrayBuffer实例有一个slice方法,允许将内存区域的一部分,拷贝生成一个新的ArrayBuffer对象。var buffer = new ArrayBuffer(8);var newBuffer = buffer.slice(0, 3);上面代码拷贝buffer对象的前3个字节(从0开始,到第3个字节前面结束),生成一个新的ArrayBuffer对象。slice方法其实包含两步,第一步是先分配一段新内存,第二步是将原来那个ArrayBuffer对象拷贝过去。slice方法接受两个参数,第一个参数表示拷贝开始的字节序号(含该字节),第二个参数表示拷贝截止的字节序号(不含该字节)。如果省略第二个参数,则默认到原ArrayBuffer对象的结尾。除了slice方法,ArrayBuffer对象不提供任何直接读写内存的方法,只允许在其上方建立视图,然后通过视图读写。ArrayBuffer.isView()ArrayBuffer有一个静态方法isView,返回一个布尔值,表示参数是否为ArrayBuffer的视图实例。这个方法大致相当于判断参数,是否为TypedArray实例或DataView实例。var buffer = new ArrayBuffer(8);ArrayBuffer.isView(buffer) // falsevar v = new Int32Array(buffer);ArrayBuffer.isView(v) // trueTypedArray视图概述ArrayBuffer对象作为内存区域

[1] [2] [3] [4] [5] [6]  下一页


ECMAScript 6 二进制数组