ES6中包含一系列的對(duì)二進(jìn)制數(shù)組的包裝類友题,用于快捷的創(chuàng)建庭砍、存儲(chǔ)、操作二進(jìn)制數(shù)組豺旬。這些二進(jìn)制數(shù)組被廣泛的應(yīng)用到文件操作霉翔、數(shù)據(jù)傳輸睁蕾、canvas繪圖等場(chǎng)景中。
1. 概述
我們先從一個(gè)組件圖整體認(rèn)識(shí)一下ES6中二進(jìn)制數(shù)組相關(guān)的部分:
從圖中我們看到债朵,二進(jìn)制數(shù)組包含如下幾個(gè)部分:
- ArrayBuffer:這是一個(gè)原始的對(duì)象子眶,它直接表示了二進(jìn)制數(shù)組在內(nèi)存中的存儲(chǔ),是原始的數(shù)據(jù)類型序芦。
- ArrayBufferView:這是一個(gè)抽象概念臭杰,稱為二進(jìn)制數(shù)組視圖。由于直接操作二進(jìn)制數(shù)組比較麻煩谚中,所以ES6定義了一系列的視圖渴杆,對(duì)原始的ArrayBuffer進(jìn)行了包裝寥枝,這樣操作起來(lái)就比較方便了。
- DataView:數(shù)據(jù)視圖磁奖,是ArrayBufferView的一種實(shí)現(xiàn)囊拜,主要用于數(shù)據(jù)傳輸場(chǎng)景。主要是可以在同一個(gè)視圖中處理不同類型的數(shù)據(jù)点寥。
- TypedArray:另外一種視圖實(shí)現(xiàn)艾疟,但是它不是一個(gè)實(shí)現(xiàn),而是一系列實(shí)現(xiàn)的總稱敢辩,都是與具體數(shù)據(jù)類型綁定的。包括:Int8Array Uint8Array
Uint8ClampedArray Int16Array Uint16Array Int32Array UInt32Array Float32Array Float64Array
2. 相關(guān)API
2.1 ArrayBuffer
2.1.1 構(gòu)造方法
//構(gòu)造時(shí)需要制定數(shù)組長(zhǎng)度弟疆,一如C語(yǔ)言一樣
//單位是字節(jié)戚长, 默認(rèn)值都是0
var buffer = new ArrayBuffer(32);
2.1.2 byteLength 屬性
存儲(chǔ)分配給當(dāng)前ArrayBuffer的字節(jié)長(zhǎng)度。
2.1.3 slice方法
表示將原數(shù)組中的字節(jié)拷貝出一部分怠苔,生成新的數(shù)組同廉。
//參數(shù)分別為起止字節(jié)序號(hào),左閉右開柑司,也就是不包含右側(cè)序號(hào)處的內(nèi)容迫肖。
//省略第二個(gè)參數(shù)表示直接到結(jié)尾
var newBuffer = oldBuffer.slice(1, 3);
2.1.4 ArrayBuffer.isView
此處抄阮大神的代碼:
var buffer = new ArrayBuffer(8);
ArrayBuffer.isView(buffer) // false
var v = new Int32Array(buffer);
ArrayBuffer.isView(v) // true
2.2 TypedArray
2.2.1 構(gòu)造方法
以Uint8Array為例,可用形式如下
//只指定長(zhǎng)度攒驰,創(chuàng)建空的視圖
var uint8Array1 = new Uint8Array(32);
var buffer = new ArrayBuffer(32);
//使用buffer創(chuàng)建視圖蟆湖,將從buffer的0序號(hào)開始到buffer末尾。
var uint8Array2 = new Uint8Array(buffer);
//從buffer的第二個(gè)字符開始玻粪,直到buffer末尾建立視圖
var uint8Array3 = new Uint8Array(buffer, 2);
//從buffer的第二個(gè)字符開始隅津,建立長(zhǎng)度為3的視圖
var uint8Array4 = new Uint8Array(buffer, 2, 3);
//從一個(gè)TypedArray拷貝建立另外一個(gè)視圖。
//由于是拷貝劲室,所以底層內(nèi)存對(duì)應(yīng)的是兩塊伦仍。
var int8Array = new Int8Array(new Uint8Array(32));
//從普通數(shù)組建立視圖
//此處也是拷貝操作,對(duì)應(yīng)的底層內(nèi)存不是同一塊很洋。
var uint8Array5 = new Uint8Array5([1, 3, 5, 7]);
2.2.2 數(shù)組操作
對(duì)數(shù)組的所有操作充蓝,完全適用于TypedArray,包括遍歷操作喉磁。
for (let item of uint8Array){
console.log(item);
}
2.2.3 BYTE_PER_ELEMENT屬性
每一種類型的TypedArray視圖都有一個(gè)屬性谓苟,用于表示該類型中一個(gè)元素所占的字節(jié)數(shù):
Int8Array.BYTES_PER_ELEMENT // 1
Uint8Array.BYTES_PER_ELEMENT // 1
Int16Array.BYTES_PER_ELEMENT // 2
Uint16Array.BYTES_PER_ELEMENT // 2
Int32Array.BYTES_PER_ELEMENT // 4
Uint32Array.BYTES_PER_ELEMENT // 4
Float32Array.BYTES_PER_ELEMENT // 4
Float64Array.BYTES_PER_ELEMENT // 8
2.2.4 buffer屬性
當(dāng)前視圖對(duì)應(yīng)的內(nèi)存段,也就是ArrayBuffer對(duì)象线定。
2.2.5 byteOffset和byteLength屬性
由于視圖是在底層內(nèi)存(ArrayBuffer)上建立的娜谊,因此保存了其在該內(nèi)存段(ArrayBuffer)的起始位置和長(zhǎng)度。
這個(gè)屬性是只讀的斤讥,也就是說(shuō):一旦建立就不可以更改了纱皆。
2.2.6 length屬性
不同于byteLength, 這個(gè)屬性是指bit長(zhǎng)度湾趾。
2.2.7 set方法
拷貝一份原視圖,由于是拷貝派草,所以建立了新的底層內(nèi)存段搀缠。由于是整段拷貝,所以特別快近迁。
var a = new Uint8Array(8);
var b = new Uint8Array(10);
//從b的第二個(gè)位(不是字符哦)開始拷貝a的內(nèi)存到b中
//第二個(gè)參數(shù)可以省略艺普,表示從第0位拷貝。
b.set(a, 2);
2.2.8 subarray方法
//從第一位到第三位創(chuàng)建新的視圖鉴竭,在原有的底層內(nèi)存上歧譬。
var newArray = oldArray.subarray(1, 3); //左閉右開
2.2.9 slice 方法
//從倒數(shù)第二位開始創(chuàng)建新的視圖,底層內(nèi)存不變
var newArray = oldArray.slice(-2);
2.2.10 TypedArray.of 方法
//通過(guò)一系列的參數(shù)創(chuàng)建一個(gè)視圖
var a = Uint8Array.of(1, 3, 5);
2.2. 11 TypedArray.from方法
這個(gè)方法與構(gòu)造方法相同搏存。
2.3 DataView
參考鏈接
- 阮一峰瑰步, 二進(jìn)制數(shù)組