[javascript]类型化数组

很久很久以前,有一个叫Array的魔王占领着javascript的数组宝座,垄断了一切形式的数组。它能屈能伸,功能齐全,也不挑食,什么类型的数据都吃。

直到有一天,ArrayBuffer家族踏上了这片土地,Array的安宁被打破了。

ArrayBuffer家里有一大群兄弟姐妹,名字叫 Float32ArrayFloat64ArrayInt8ArrayInt16ArrayInt32ArrayUint8ArrayUint16ArrayUint32Array (还有和数组没关系的就不写了)。他们来找Array挑战:
Array:我能力超强!
ArrayBuffers:我们效率高

Array:我功能齐全!
ArrayBuffers:我们效率高

Array:我声明简单!
ArrayBuffers:我们效率高

Array:我屮艸芔茻!
ArrayBuffers:我们效率高

算了还是回主题吧。。编不下去了。。。
类型化数组是已经存在了不少时间的“新”数组类型了,因为它是类型化数组,所以它的效率不用质疑肯定比Array对象要高很多,适合用来做计算量很大的多数字操作,比如矩阵计算。也可以单纯用来节省内存开销,如果你已经知道数据会在什么范围,那么可以尽可能选择位数少的类型话数组,这样在存储相同的数字时,一般是比Array节省内存的。

类型化数组实质上都是ArrayBuffer的扩充,也就是除了ArrayBuffer,再加上几个可以标识特殊身份的属性,不同的ArrayBuffer也就有了不一样的属性和用处。比如列一下Uint8ArrayUint32Array的属性可以看到

 //无符号8位整数
new Uint8Array([123,234,222,33,232,23,122])
Uint8Array[7]    
0: 123
1: 234
2: 222
3: 33
4: 232
5: 23
6: 122
buffer: ArrayBuffer
byteLength: 7
__proto__: ArrayBuffer
byteLength: get byteLength: function byteLength() { [native code] }
constructor: function ArrayBuffer() { [native code] }
slice: function slice() { [native code] }
__proto__: Object
byteLength: 7
byteOffset: 0
length: 7
__proto__: Uint8Array



//无符号32位整数
new Uint32Array([2322,1805083958,2343424234,2342343])
Uint32Array[4]
0: 2322
1: 1805083958
2: 2343424234
3: 2342343
buffer: ArrayBuffer
byteLength: (...)
__proto__: ArrayBuffer
byteLength: 16
byteOffset: 0
length: 4__proto__: Uint32Array

新建一个类型化数组可以这样
new Int32Array(1024) //括号里是数组大小
//这样创建的数组所有位默认用0填充

也可以这样
new Int32Array([321,654,7892,5465,987]) //直接定义了各个元素

如果给类型化数组的数字超出了它的数据范围,那就会数位溢出,像这样
new Int8Array([123124])//输入
[-12]//输出

访问其中的数据和Array是一样的
var a=new Int32Array([1231,8798,654,325647,45])
a[0]  //1231
a[1]  //8798
//....

正是因为类型化数组在生成的时候就开辟了一块连续的内存空间,不像Array有索引和字典两种存放模式,所以其效率才会比Array高。

类型化数组的缺点就是
·既然类型化了那就只能放指定类型的数据,不能把对象什么的放在里面,更不能用多维数组了
·不能像Array那样随便删除和添加元素,也就是不能直接伸长缩短,但是可以手动把两个数组合并成1个新的长数组,也可以从一个数组里提一块出来成为一个新数组
·在IntArray里超出数据范围不会像普通的数字变量一样变成Infinity,而是0

数组取段
类型化数组都有一个subarray方法,可以把数组里的某一段取出来,变成一个新的数组

var a=new Int32Array([1231,8798,654,325647,123232])
a.subarray(1,4)
[8798, 654, 325647]//输出

输出的数组和原本的数组类型一样

拼接两个数组
类型化数组不可以直接伸长,因为他的大小在创建的时候就定死了,这时我们想要增加这个数组的长度,可以这么做

//只能遍历把两个数组合并成一个新数组
var a=new Int32Array([1231,8798,654,325647,123232]);
var b=new Int32Array([321,654,7892,5465,987]);
var c=new Int32Array(a.length+b.length);
var offset=0;
for(var i=0;i<a.length;i++){
 c[offset]=a[i];
 offset++;
}
for(var i=0;i<b.length;i++){
 c[offset]=b[i];
 offset++;
}

c; //[1231, 8798, 654, 325647, 123232, 321, 654, 7892, 5465, 987]

参考:
·巨硬的文档
·如何高大上地凑博文



本文发布于 https://luojia.me

本站文章未经文下加注授权不得拷贝发布。

本博客使用Disqus评论系统,如果看不到评论框,请尝试爬墙。