javascript是一种弱语言类型,自带Array构造函数用于构造数组,但是在Web Audio和webgl中需要传输的数据往往需要很高精度,这时候使用数组就不起作用了,需要引入C语言中类似的32位或者64位的浮点数。
在js中数组的创建一般使用new Array(5);或者直接给出数组。
var a = new Array(5);//初始化a是含有5个undefined的数组,可以通过改变a.length改变a的长度。
而ArrayBuffer开辟了一段数组缓冲区。
var b = new ArrayBuffer(12);
ArrayBuffer只能定义长度,无法直接读取它的内容,使用b.byteLength获取缓存区长度。
数组缓冲区长为12个字节。每个字节含有八位。
var x = new Float32Array(2);//初始化x是[0,0]。
创建了一个长度为2的32bit浮点数,每个浮点数是用4个字节表示,但是跟Array不同的是,TypedArray构造之后它的长度不能变,即使x.length = 3; console.log(x.length)//依旧输出2。
var x = new Float32Array([1,34.567]);console.log(x);
创建类型化数组之后得到的并不是真正数组而是对象类型,并且x[1]输出34.56700134277344的32位类型的小数。如果需要转换成真正数组,需要调用Array.apply(new Array(),x);同时构造函数指向Array。
除了直接创建类型化数组,还可以操作ArrayBuffer得到类型化数组。
var buffer = new ArrayBuffer(16);
var x = new Float64Array(buffer, 8, 1);
var y = new Float32Array(buffer, 12, 1);
console.log(y[0]); // 0
x[0] = 1;
console.log(y[0]); // 1.875
第一个参数是所指向的缓冲区,第二个参数指向缓冲区的偏移位置,第三个参数是要得到的类型化数组的长度。要注意的是,缓冲区的长度必须是要类型化的数组单位的整数倍,Float64Array是8个字节长度,所以缓冲区选为8个字节的整数倍,这里是16字节长度,否则报错()。使用这种操作方式可以改变缓冲区的数据,因为参数中的第一个参数一直指向该buffer缓冲区。只不过实时选取。
var x = new Float32Array([1, -1.5]);
var y = new Float32Array(x);
console.log(x[0]); // 1
console.log(x[1]); //-1.5
console.log(y[0]); //1
x[0] = -2;
console.log(x[0]); //-2
console.log(y[0]); //1
这种方式得到的类型化数据每次new的时候建立的独立的缓冲区,数据分别存储。另外有一点知识点需要知道Function.length属性是function传入的参数的个数。上面说到对ArrayBuffer的操作除了TypedArray之外,还可以使用超类DataView。
var buffer = new ArrayBuffer(12);
var x = new DataView(buffer, 0);
x.setFloat32(0,14.33)
x.setFloat64(4, 32.55);
console.log(x.getFloat32(0)); // 14.329999923706055
console.log(x.getFloat64(4)); // 32.55
需要注意的是set和get函数的第一个参数都是缓冲区的偏移位置,偏移位置之间可能会发生覆盖。常见错误就是整个缓冲区的长度不够,数组越界。
var buffer = new ArrayBuffer(12);
var x = new DataView(buffer, 0);
x.setFloat32(0,14.33)
x.setFloat64(2, 32.55);
console.log(x.getFloat32(0)); // 14.32818603515625
console.log(x.getFloat64(1)); // 5.268287928261222e+179