新增的数组API
静态方法
-
Array.of()
返回一个数组,数组中的元素就是该函数传入的参数
const arr1 = Array.of(10); // [10] const arr2 = new Array(10); // [empty × 10] -
Array.from()
通过给定的类数组或可迭代对象来创建一个新数组,并将其返回
实例方法
-
find(callback)
返回满足条件的第一个元素,找不到则返回undefined
-
findIndex(callback)
返回满足条件的第一个元素的下标,找不到则返回-1
-
fill(data)
将数组的全部元素都填充为data
-
includes(data)
判断数组中是否存在data,使用Object.is()进行匹配
类型化数组
在JS中,无论是小数还是整数,都是使用64位的双精度浮点数来保存
因此当存储某些数时,会造成内存空间的浪费
const arr = new Array(100).fill(0);
// 虽然arr中存储的都是0,但却占用了6400bit的空间
类型化数组就是用于优化多个数字的存储
类型化数组分为:
- Int8Array:每个元素都是8位的有符号整数
- UInt8Array:每个元素都是8位无符号整数
- Int16Array
- UInt16Array
- ...
- Float32Array
- Float64Array
注意:
- 类型化数组只能存储数字
- 当类型化数组存储的数字超出所能表示的范围时,会自动舍弃其高位
创建类型化数组
使用构造方法
new Int8Array(len);
刚刚创建出的类型化数组,数组元素均为0
const arr = new Int8Array(10); // [0 × 10]
可以使用byteLength查看类型化数组所占内存的字节数量
注意:类型化数组不同于普通数组,类型化数组的构造方法只会将传入的数字作为数组的长度,而不会把它当做数组的元素
构造方法中也可以传入其他类型化数组,此时,构造方法将返回一个全新的类型化数组
const arr1 = new Int8Array(10);
const arr2 = new Int8Array(arr1);
console.log(arr1, arr2); // [0 × 10] [0 × 10]
console.log(arr1 === arr2); // false
使用静态方法of
Int8Array.of(...);
of方法会将参数作为类型化数组的元素
使用静态方法from
Int8Array.from();
from中传入可迭代对象
类型化数组的操作
类型化数组也是可迭代对象,因此可以使用for of循环
类型化数组的操作和普通数组基本一致
const arr = new Int8Array(10);
arr[0] = 100;
不过类型化数组一旦创建,长度就不能更改,即不能增加和删除元素
类型化数组的一些方法,其返回的也是同类型的类型化数组
const arr1 = new Int8Array(10);
const arr2 = arr1.map((item)=>{
return item * 2;
});
// arr2也是Int8Array的类型化数组
ArrayBuffer
ArrayBuffer就代表着一块固定大小的内存空间
创建ArrayBuffer
new ArrayBuffer(byteLength);
ArrayBuffer的实例成员
-
byteLength
得到ArrayBuffer所占空间的字节数
const ab = new ArrayBuffer(10); console.log(ab.byteLength); // 10 -
slice(start, end)
将原ArrayBuffer中的从start字节位置开始,到end字节位置为止,但不包含end字节位置的这段内存数据复制到新ArrayBuffer中,并将新ArrayBuffer返回
新ArrayBuffer的byteLength为end - start
start为起始字节,默认为0,end为结束字节,默认为byteLength
slice方法不会改变原ArrayBuffer,它仅仅只是得到一个新的ArrayBuffer
const ab1 = new ArrayBuffer(10); const ab2 = ab1.slice(3, 6); console.log(ab2.byteLength); // 3
读写ArrayBuffer
ArrayBuffer本身不具有读写内存的功能,要想让其具备读写功能则需要配合其它对象进行使用
使用数据视图
创建数据视图
const view = new DataView(ArrayBuffer, byteOffset, byteLength);
如上,表示创建一个数据视图,该数据视图可以操作ArrayBuffer中从byteOffset个字节开始,共byteLength个字节的内存数据
byteOffset和byteLength超出有效值时会报错
写数据
-
view.setInt8(offset, data)
表示针对view可操作的部分中,向后偏移offset个字节,将从该位置开始的之后8个bit的数据设置为data
-
view.setInt16(offset, data)
表示针对view可操作的部分中,向后偏移offset个字节,将从该位置开始的之后16个bit的数据设置为data
-
view.setInt32(offset, data)
-
...
读数据
-
view.getInt8(offset)
得到view可操作的部分中,向后偏移offset个字节,取出从该位置开始的之后8个bit的数据
-
view.getInt16(offset)
得到view可操作的部分中,向后偏移offset个字节,取出从该位置开始的之后16个bit的数据
-
view.getInt32(offset, data)
-
...
使用类型化数组
类型化数组中有一个buffer属性,它其实就是一个ArrayBuffer,该ArrayBuffer中保存的就是类型化数组中的数据
若创建类型化数组时不为其指定ArrayBuffer,则类型化数组会为自己创建一个新的ArrayBuffer
若创建类型化数组时传递的参数是ArrayBuffer,则该类型化数组的buffer属性就为该ArrayBuffer,这也表示类型化数组对应的内存空间就是ArrayBuffer
将类型化数组的空间与ArrayBuffer对应后,对ArrayBuffer的读写,就变成了对类型化数组的读写
多个类型化数组可以对应同一个ArrayBuffer
const ab = new ArrayBuffer(10);
const arr1 = new Int8Array(ab);
const arr2 = new Int8Array(ab);
console.log(arr1.buffer === ab); // true
console.log(arr2.buffer === arr1.buffer); // true
将同一个ArrayBuffer与多个类型化数组关联后,其中一个类型化数组对ArrayBuffer的修改,会影响到其他类型化数组
arr1[0] = 10;
console.log(arr2[0]); // 10
注意:这里是以Int8Array举例,因此操作ArrayBuffer时,每次操作的是一个字节,若将Int16Array与ArrayBuffer关联,则每次操作的是两个字节