一個(gè) TypedArray
對(duì)象描述了一個(gè)二進(jìn)制數(shù)組緩沖器(Buffer)的類(lèi)數(shù)組 (array-like) 視圖衍慎。TypeArray
是一個(gè)概念垦搬,既不存在于全局 (global) 對(duì)象中,也沒(méi)有自己的構(gòu)造函數(shù) (constructor)识樱,它是一系列擁有特定類(lèi)型 (specific element types) 的數(shù)組的集合體嗤无,這類(lèi)型的數(shù)組我們稱(chēng)為 Typed Array (有類(lèi)型的數(shù)組)。
我們知道 JS 的數(shù)組里面可以放各種類(lèi)型的數(shù)據(jù)牺荠,在 Typed Array
的數(shù)組中翁巍,我們要求數(shù)組中的數(shù)據(jù)都是其指定的類(lèi)型。
TypedArray
擁有11種類(lèi)型休雌,依次是:
- Int8Array
- Uint8Array
- Uint8ClampedArray
- Int16Array
- Uint16Array
- Int32Array
- Uint32Array
- Float32Array
- Float64Array
- BigInt64Array
- BigUint64Array
上面這些類(lèi)型擁有相同的構(gòu)造方法(把下面的 TypedArray
替換成對(duì)應(yīng)的類(lèi)型)
// 多種構(gòu)造方式
new TypedArray();
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);
每個(gè)類(lèi)型的常用方法基本等同于傳統(tǒng)的 Array
灶壶,這里就不贅述了。
說(shuō)了相同點(diǎn)杈曲,下面來(lái)看看不同點(diǎn)驰凛。每個(gè)類(lèi)型區(qū)別在于數(shù)組中元素的取值范圍 (Value Range) 的不同,例如 Uint8Array
里面元素的類(lèi)型是無(wú)符號(hào)8字節(jié)担扑,范圍就是 0 ~ 255(= 2? - 1) 恰响。
下面我們用一段代碼來(lái)對(duì)取值范圍做進(jìn)一步研究
var uint8 = new Uint8Array(10)
var a = uint8[0] = 255
var b = uint8[1] = 256
var c = uint8[2] = 257
上面 a
b
c
unit8[0]
unit8[1]
unit8[2]
的值分別是多少?大家先自己想想涌献。
公布答案:255胚宦、256、257燕垃、255枢劝、0、1
Unit8Array
會(huì)對(duì)每個(gè)元素進(jìn)行取模 (%) 運(yùn)算:255 % 256 = 255卜壕、256 % 256 = 0 ...
至于像 Int8Array
(取值范圍 -127 ~ 128) 這種帶符號(hào)的您旁,會(huì)涉及到補(bǔ)位的概念,稍微有點(diǎn)復(fù)雜轴捎,這里不做進(jìn)一步深入鹤盒,大家不了解的可以去查一些數(shù)據(jù)基礎(chǔ)方面的資料。
那么當(dāng)我們對(duì)元素賦非數(shù)字的值的時(shí)候侦副,會(huì)發(fā)生什么呢侦锯?
var uint8 = new Uint8Array(10)
uint8[0] = 'abc'
uint8[1] = '123hello'
uint8[2] = '444'
uint8[3] = true
uint8[4] = false
結(jié)果分別是:0、0秦驯、258率触、1、0。你答對(duì)了嗎葱蝗?
背后的邏輯就是 TypedArray
會(huì)對(duì)賦的值進(jìn)行 Number(value)
操作穴张。
還有要注意的是,TypedArray
的長(zhǎng)度是在初始化 (new) 的時(shí)候就固定 (fixed-length) 的两曼,并不能像普通 Array
那樣動(dòng)態(tài)改變數(shù)組長(zhǎng)度皂甘。例如:
var uint8 = new Uint8Array(10)
uint8[11] = 100
console.log(uint8[11])
控制臺(tái)打出的結(jié)果是 undefined
總的來(lái)說(shuō),TypedArray
數(shù)組的作用悼凑,是確保每個(gè)元素都是在一定的范圍內(nèi)的整數(shù)或浮點(diǎn)數(shù)偿枕,為一些特定業(yè)務(wù)的處理提供了便捷。
說(shuō)完 TypedArray
户辫,我們來(lái)說(shuō)說(shuō) ArrayBuffer
渐夸。ArrayBuffer
在其他開(kāi)發(fā)語(yǔ)言中常被成為 Byte Array
,它也是個(gè)定長(zhǎng) (fixed-length) 的數(shù)組渔欢。由于 ArrayBuffer
不能直接進(jìn)行操作墓塌,所以通常用 TypeArray
或 DataView
對(duì)其進(jìn)行封裝后再進(jìn)行操作。下圖展示了 ArrayBuffer
的結(jié)構(gòu)并對(duì)其直接操作:
我們看到對(duì) ArrayBuffer
用數(shù)組的方式賦值奥额,其實(shí)就是創(chuàng)建了新的屬性苫幢。那么按照上面說(shuō)的,要操作 ArrayBuffer
垫挨,我們需要先對(duì)齊進(jìn)行封裝
var uint8 = new Uint8Array(arrayBuffer)
uint8[3] = 17
這時(shí)候我們?cè)賮?lái)看下結(jié)果韩肝,見(jiàn)下圖
ArrayBuffer
的實(shí)例除了通過(guò) new
函數(shù)獲得,文件的讀寫(xiě)操作喝 Base64 的轉(zhuǎn)換也能從中獲得 ArrayBuffer
九榔。