Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

JavaScript的“强类型数组”简介

  我们平时使用的Array对象说它是数组,其实是一个从哈希表扩展的结构体。因此它可以提供push、splice等一些列操作。这就意味着他们的效率是很低的。在JavaScript中也可以创建真正的数组,那就是强类型数组。这个概念在以前的JavaScript中是没有的,由于现在JavaScript的发展,它变得可以调用一些系统底层的东西比如WebGL。这些底层的操作需要直接访问内存,而JavaScript本身的Array在内存中是分散无法与底层操作对接,因此引入了这些强类型的数组。
  强类型数组有三种基本类型:
    Int 整数
    Uint 无符号整数
    Float IEEE754浮点数
  根据这些基本类型可以引申出8种类数组:
    Int8Array
    Uint8Array
    Int16Array
    Uint16Array
    Int32Array
    Uint32Array
    Float32Array
    Float64Array
  这些东西没必要一个个去说明,他们的规律性很强。这些数组的命名都是:基本类型+位数+Array。我们都知道一个字节是8位的,所以8位的数组中每个元素就占一个字节。同理可知64位的数组每个元素占8个字节。就拿Int8Array来说,它是8位的整数。8位可以表示28=256个数字。而Int是有符号的,所以Int8Array的元素可以表示-128到127的整数。而Uint8Array的元素是无符号的,同理可知它可以表示0-255的整数。
  由于这些数组是使用线性储存,因此它们是定长的,无法给数组添加元素。超出索引的赋值不会报错,也不会生效。下面是一个简单的使用例子。
//创建一个具有3个元素的8为无符号整型数组
var a=new Uint8Array(3);
//把Array对象转换成无符号数组
var b=new Uint8Array([1,2,3]);
//输出到控制台
console.log(a);
console.log(b);

  这是最常用的两种创建方式。第一中是传入数组大小,这里我们传入3,所以结果中输出的数组有3个元素。而且这样创建的数组把元素都初始化为0,不像C++中的new int不做初始化。第二种是传入一个Array对象,转换为Uint8Array。这样得到的数组每一项的值就是原来Array对象中每一项的值。另外值得一提的是使用这个方法初始化时候,Array的元素是通过调用valueOf来转换成数值的,无法转换的数据则被置0。看下面这个例子 <script>
var o={
  valueOf:function(){
    return 123;
  }
};
console.log(new Uint8Array([o,"123","xyz"]));

  除了这两种初始化方式外还有另一只不常用的方式。使用ArrayBuffer,也就是传入一块内存指针来创建数组。ArrayBuffer的功能和C语言中的malloc相似,就是申请一块连续的内存,只不过它不需要手动释放内存而已。系统也不会直接返回个指针给JavaScript,ArrayBuffer的返回值是一个封装成了对象的指针,我们就称它为缓冲区吧。下面是使用这个玩意儿的例子。
var buf=new ArrayBuffer(4);
var a=new Uint16Array(buf);
console.log(a);
  这个测试我就不截图了,a这个数组只有两个元素。因为Uint16Array是16位的,也就是每个元素占两个字节。而之前申请的内存控件是4个字节,因此生成的数组只有两个元素。也许你会好奇,如果申请的内存空间的字节数为奇数,再转换成Uint16Array结果会如何呢?试试就知道 var buf=new ArrayBuffer(3);
var a=new Uint16Array(buf);
console.log(a);

  这样是会报错的。刻意去使用ArrayBuffer的情况比较少,除非要让两个数组使用同一块内存空间。比如下面这个例子。 var buf=new ArrayBuffer(2);
var a=new Uint8Array(buf);
var b=new Int8Array(buf);
a[0]=100;
a[1]=200;
console.log(a);
console.log(b);

  这个例子中两个不同类型的数组使用了同一块内存空间。第一个元素是100,在Uint和Int中都可以显示为100;而第二个元素是200,Int8Array的数据最大值是127,因此溢出导致数组倒转-128+200-128=-56。这就是不同类型的数组使用同一块内存空间。不仅是有无符号的区别,我们可以利用这个特性把32位的数组和8位的数组使用同一块内存控件来完成我们需要的操作,这里就不举例了。
  到这里“强类型数组”就基本介绍完了,如果有兴趣深入研究可以去查看官方文档。
  MDN JavaScript Typed Arrays
网名:
52.91.185.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^