本文最后更新于:2023年1月12日 下午
定型数组(typed array) 定型数组(typed array)
是ECMAScript
新增的结构,目的是提升向原生库传输数据的效率。实际上,JavaScript
并没有"TypedArray"
类型,它所指的其实是一种特殊的包含数值类型的数组
ArrayBuffer ArrayBuffer
是所有定型数组及视图引用的基本单位 。
SharedArrayBuffer
是ArrayBuffer
的一个变体,可以无须复制就在执行上下文间传递它
1 2 3 const buf = new ArrayBuffer (2 ) console .log (buf) console .log (buf.byteLength )
ArrayBuffer
一经创建就不能再调整大小
1 2 3 const buf = new ArrayBuffer (16 )const buf2 = buf.slice (4 , 12 ) console .log (buf2.byteLength )
ArrayBuffer
分配的堆内存可以被当成垃圾回收,不用手动释放(相比于C/C++
的malloc()
)
DataView DataView
用于读写ArrayBuffer
的视图。专为文件I/O
和网络I/O
设计,其API
支持对缓冲数据的高度控制,但较其他类型的视图,性能差一些。
必须对已有的ArrayBuffer
进行读/写才能创建DataView
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 const buf = new ArrayBuffer (16 )const dv = new DataView (buf) console .log (dv) console .log (dv.byteLength ) console .log (dv.byteOffset ) console .log (dv.buffer === buf) const dv2 = new DataView (buf, 2 , 4 )console .log (dv2) console .log (dv2.byteLength ) console .log (dv2.byteOffset ) console .log (dv2.buffer === buf)
读取缓冲,需要几个ElementType
组件,类似于C
中的类型
1 2 3 4 5 6 7 8 9 10 11 const buf = new ArrayBuffer (16 )const dv = new DataView (buf, 0 , 8 )console .log (dv.getInt8 (0 )) console .log (dv.getInt8 (1 )) console .log (dv.getInt16 (0 )) dv.setInt8 (1 , 255 ) console .log (dv.getInt8 (1 )) console .log (dv.getUint8 (1 ))
除了上述的类型(Int8, Uint8, Int16
)还有Uint16,Int32, Uint32, Float32, Float64
。默认的字节序为大端字节序。传递第二个参数可以决定字节序,为true
时,则启用小端字节序
DataView
只支持两种约定:大端字节序和小端字节序。大端字节序也称为“网络字节序”,意思是最高有效位保存在第一个字节,而最低有效位保存在最后一个字节。小端字节序正好相反,即最低有效位保存在第一个字节,最高有效位保存在最后一个字节。
DataView
的读、写操作都必须满足充足的缓冲区,如果越界会抛出RangError
1 2 3 4 const buf = new ArrayBuffer (2 )const dv = new DataView (buf) dv.getInt32 (0 )
定型数组 定型数组是另一种形式的ArrayBffer
视图。设计定型数组的目的就是提高与 WebGL
等原生库交换二进制数据的效率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 const buf = new ArrayBuffer (12 )const ints = new Int32Array (buf)console .log (ints) console .log (ints.length ) console .log (ints.buffer ) const ints1 = new Int32Array (6 )console .log (ints1.length ) const ints2 = new Int32Array ([1 , 2 , 3 , 4 ])console .log (ints2.length ) console .log (ints2[1 ]) const ints3 = Int32Array .from (ints2)const ints4 = Int32Array .of (10 , 20 , 30 , 40 )console .log (ints3.length ) console .log (ints4.length ) console .log (ints3[1 ]) console .log (ints4[1 ]) console .log (Int32Array .BYTES_PER_ELEMENT ) console .log (Float64Array .BYTES_PER_ELEMENT ) console .log (ints4.BYTES_PER_ELEMENT )
定型数组支持数组的方法和属性,包括Symbol.iterator
符号属性,但是没有concat(), poop(), push(), shift(), unshift(), splice()
。定型数组提供了两个方法可以实现复制数据:set()
和subarray()
set()
从提供的数组或定型数组中把值复制到当前的定型数组中指定索引位置
1 2 3 4 5 6 7 const container = new Int8Array (8 ) container.set (new Int8Array ([2 , 3 , 4 , 5 ]), 2 )console .log (container) container.set (new Int8Array ([3 , 4 ,5 ]), 7 )
subarray()
会基于原始定型数组返回复制的值组成新的定型数组
1 2 3 4 5 const source = new Int8Array ([1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ])const newSource = source.subarray (2 , 4 )console .log (newSource) console .log (newSource)
除了8
种元素类型,还有一种”夹板“数组类型:Uint8ClampedArray
,用于解决溢出问题。该类型不允许任何方向溢出,超出最大值255
的值会被向下舍入为255
,而小于最小值0
的值会被向上舍入为0
1 2 const clampedInts = new Uint8ClampedArray ([-1 , 0 , 255 , 256 ])console .log (clampedInts)
除非做的和canvas
相关开发,否则不要使用它