TypedArray
Baseline 廣泛可用 *
一個 TypedArray 物件描述了底層二進位制資料緩衝區的類陣列檢視。沒有名為 TypedArray 的全域性屬性,也沒有直接可見的 TypedArray 建構函式。相反,有許多不同的全域性屬性,其值是針對特定元素型別的型別化陣列建構函式,如下所示。在以下頁面中,你將找到可與包含任何型別的元素的任何型別化陣列一起使用的常用屬性和方法。
描述
TypedArray 建構函式(通常稱為 %TypedArray% 以表示其“內在性”,因為它不對應於任何暴露給 JavaScript 程式的全域性物件)作為所有 TypedArray 子類的共同超類。可以將 %TypedArray% 視為一個“抽象類”,為所有型別化陣列子類提供通用實用方法介面。此建構函式不直接公開:沒有全域性 TypedArray 屬性。它只能透過 Object.getPrototypeOf(Int8Array) 等方式訪問。
建立 TypedArray 子類(例如 Int8Array)的例項時,會在記憶體中內部建立一個數組緩衝區,或者,如果將 ArrayBuffer 物件作為建構函式引數給出,則使用該 ArrayBuffer。緩衝區地址作為例項的內部屬性儲存,並且 %TypedArray%.prototype 的所有方法都將根據該陣列緩衝區地址設定和獲取值。
TypedArray 物件
| 型別 | 值範圍 | 大小(位元組) | Web IDL 型別 |
|---|---|---|---|
Int8Array |
-128 到 127 | 1 | byte |
Uint8Array |
0 到 255 | 1 | octet |
Uint8ClampedArray |
0 到 255 | 1 | octet |
Int16Array |
-32768 到 32767 | 2 | short |
Uint16Array |
0 到 65535 | 2 | unsigned short |
Int32Array |
-2147483648 到 2147483647 | 4 | long |
Uint32Array |
0 到 4294967295 | 4 | unsigned long |
Float16Array |
-65504 到 65504 |
2 | N/A |
Float32Array |
-3.4e38 到 3.4e38 |
4 | unrestricted float |
Float64Array |
-1.8e308 到 1.8e308 |
8 | 無限制雙精度 |
BigInt64Array |
-263 到 263 - 1 | 8 | bigint |
BigUint64Array |
0 到 264 - 1 | 8 | bigint |
值編碼和規範化
所有型別化陣列都在 ArrayBuffer 上操作,你可以在其中觀察每個元素的精確位元組表示,因此數字在二進位制格式中的編碼方式非常重要。
- 無符號整數陣列(
Uint8Array、Uint16Array、Uint32Array和BigUint64Array)直接以二進位制形式儲存數字。 - 有符號整數陣列(
Int8Array、Int16Array、Int32Array和BigInt64Array)使用二進位制補碼儲存數字。 - 浮點陣列(
Float16Array、Float32Array和Float64Array)使用IEEE 754 浮點格式儲存數字。Number引用中有關於精確格式的更多資訊。JavaScript 數字預設使用雙精度浮點格式,這與Float64Array相同。Float32Array使用 23 位(而不是 52 位)表示尾數,8 位(而不是 11 位)表示指數。Float16Array使用 10 位表示尾數,5 位表示指數。請注意,規範要求所有NaN值使用相同的位編碼,但確切的位模式取決於實現。 Uint8ClampedArray是一個特殊情況。它像Uint8Array一樣以二進位制形式儲存數字,但是當儲存超出範圍的數字時,它會透過數學值將數字“鉗制”到 0 到 255 的範圍,而不是截斷最高有效位。
除 Int8Array、Uint8Array 和 Uint8ClampedArray 之外的所有型別化陣列都使用多個位元組儲存每個元素。這些位元組可以從最高有效到最低有效(大端序)或從最低有效到最高有效(小端序)排序。有關更多說明,請參閱位元組序。型別化陣列始終使用平臺的本機位元組序。如果要在從緩衝區寫入和讀取時指定位元組序,則應改用 DataView。
寫入這些型別化陣列時,超出可表示範圍的值將進行規範化。
- 所有整數陣列(
Uint8ClampedArray除外)都使用固定寬度數字轉換,它首先截斷數字的小數部分,然後取最低位。 Uint8ClampedArray首先將數字鉗制到 0 到 255 的範圍(大於 255 的值變為 255,小於 0 的值變為 0)。然後它將結果“四捨五入”(而不是向下取整)到最接近的整數,採用半舍到偶數;這意味著如果數字恰好介於兩個整數之間,它將四捨五入到最接近的偶數整數。例如,0.5變為0,1.5變為2,2.5變為2。Float16Array和Float32Array執行“四捨五入到偶數”以將 64 位浮點數轉換為 32 位和 16 位。這與Math.fround()和Math.f16round()提供的演算法相同。
檢視可調整大小的緩衝區時的行為
當 TypedArray 作為可調整大小的緩衝區的檢視建立時,調整底層緩衝區的大小將對 TypedArray 的大小產生不同的影響,具體取決於 TypedArray 是否被構造為長度跟蹤。
如果建立型別化陣列時未指定特定大小(透過省略第三個引數或傳遞 undefined),則型別化陣列將變為“長度跟蹤”,並且會隨著底層 buffer 的調整大小而自動調整以適應它。
const buffer = new ArrayBuffer(8, { maxByteLength: 16 });
const float32 = new Float32Array(buffer);
console.log(float32.byteLength); // 8
console.log(float32.length); // 2
buffer.resize(12);
console.log(float32.byteLength); // 12
console.log(float32.length); // 3
如果使用第三個 length 引數建立具有特定大小的型別化陣列,則它不會隨著 buffer 的增長而調整大小以包含 buffer。
const buffer = new ArrayBuffer(8, { maxByteLength: 16 });
const float32 = new Float32Array(buffer, 0, 2);
console.log(float32.byteLength); // 8
console.log(float32.length); // 2
console.log(float32[0]); // 0, the initial value
buffer.resize(12);
console.log(float32.byteLength); // 8
console.log(float32.length); // 2
console.log(float32[0]); // 0, the initial value
當 buffer 縮小時,檢視的型別化陣列可能會超出範圍,在這種情況下,型別化陣列的觀察大小將減小到 0。這是非長度跟蹤型別化陣列長度可能改變的唯一情況。
const buffer = new ArrayBuffer(8, { maxByteLength: 16 });
const float32 = new Float32Array(buffer, 0, 2);
buffer.resize(7);
console.log(float32.byteLength); // 0
console.log(float32.length); // 0
console.log(float32[0]); // undefined
如果你隨後再次增大 buffer 以使型別化陣列回到界限內,則型別化陣列的大小將恢復到其原始值。
buffer.resize(8);
console.log(float32.byteLength); // 8
console.log(float32.length); // 2
console.log(float32[0]); // 0 - back in bounds again!
如果緩衝區縮小到 byteOffset 之外,長度跟蹤型別化陣列也可能發生同樣的情況。
const buffer = new ArrayBuffer(8, { maxByteLength: 16 });
const float32 = new Float32Array(buffer, 4);
// float32 is length-tracking, but it only extends from the 4th byte
// to the end of the buffer, so if the buffer is resized to be shorter
// than 4 bytes, the typed array will become out of bounds
buffer.resize(3);
console.log(float32.byteLength); // 0
建構函式
此物件無法直接例項化 — 嘗試使用 new 構造它會丟擲 TypeError。
new (Object.getPrototypeOf(Int8Array))();
// TypeError: Abstract class TypedArray not directly constructable
相反,你建立特定型別的型別化陣列例項,例如 Int8Array 或 BigInt64Array。這些物件都有一個共同的建構函式語法。
new TypedArray()
new TypedArray(length)
new TypedArray(typedArray)
new TypedArray(object)
new TypedArray(buffer)
new TypedArray(buffer, byteOffset)
new TypedArray(buffer, byteOffset, length)
其中 TypedArray 是具體型別之一的建構函式。
引數
typedArray-
當使用
TypedArray子類的例項呼叫時,typedArray會被複制到一個新的型別化陣列中。對於非 bigintTypedArray建構函式,typedArray引數只能是以下非 bigint 型別之一(例如Int32Array)。類似地,對於 bigintTypedArray建構函式(BigInt64Array或BigUint64Array),typedArray引數只能是以下 bigint 型別之一。typedArray中的每個值在複製到新陣列之前都會轉換為建構函式的相應型別。新型別化陣列的長度將與typedArray引數的長度相同。 object-
當使用非
TypedArray例項的物件呼叫時,將以與TypedArray.from()方法相同的方式建立一個新的型別化陣列。 length可選-
當使用非物件呼叫時,引數將被視為指定型別化陣列長度的數字。記憶體中會建立一個內部陣列緩衝區,大小為
length乘以BYTES_PER_ELEMENT位元組,並用零填充。省略所有引數等同於使用0作為length。 buffer、byteOffset可選、length可選-
當使用
ArrayBuffer或SharedArrayBuffer例項呼叫時,以及可選的byteOffset和length引數,將建立一個新的型別化陣列檢視來檢視指定的緩衝區。byteOffset(以位元組為單位)和length(以元素數量為單位,每個元素佔用BYTES_PER_ELEMENT位元組)引數指定型別化陣列檢視將公開的記憶體範圍。如果兩者都省略,則檢視buffer的全部內容;如果只省略length,則檢視從byteOffset開始的buffer的剩餘部分。如果省略length,則型別化陣列將變為長度跟蹤。
異常
所有 TypeArray 子類建構函式都以相同的方式操作。它們都會丟擲以下異常:
TypeError-
在以下情況之一中丟擲
- 傳入了一個
typedArray,但它是一個 bigint 型別,而當前建構函式不是,反之亦然。 - 傳入了一個
typedArray,但它正在檢視的緩衝區已分離,或者直接傳入了一個已分離的buffer。
- 傳入了一個
RangeError-
在以下情況之一中丟擲
- 新型別化陣列的長度過大。
buffer的長度(如果未指定length引數)或byteOffset不是新型別化陣列元素大小的整數倍。byteOffset不是有效的陣列索引(一個介於 0 和 253 - 1 之間的整數)。- 從緩衝區建立檢視時,邊界超出緩衝區。換句話說,
byteOffset + length * TypedArray.BYTES_PER_ELEMENT > buffer.byteLength。
靜態屬性
這些屬性在 TypedArray 建構函式物件上定義,因此由所有 TypedArray 子類建構函式共享。
TypedArray[Symbol.species]-
用於建立派生物件的建構函式。
所有 TypedArray 子類還具有以下靜態屬性:
TypedArray.BYTES_PER_ELEMENT-
返回不同
TypedArray物件的元素大小的數字值。
靜態方法
這些方法在 TypedArray 建構函式物件上定義,因此由所有 TypedArray 子類建構函式共享。
TypedArray.from()-
從類陣列或可迭代物件建立新的
TypedArray。另請參見Array.from()。 TypedArray.of()-
使用可變數量的引數建立新的
TypedArray。另請參見Array.of()。
例項屬性
這些屬性在 TypedArray.prototype 上定義,並由所有 TypedArray 子類例項共享。
TypedArray.prototype.buffer-
返回型別化陣列引用的
ArrayBuffer。 TypedArray.prototype.byteLength-
返回型別化陣列的長度(以位元組為單位)。
TypedArray.prototype.byteOffset-
返回型別化陣列相對於其
ArrayBuffer起始位置的偏移量(以位元組為單位)。 TypedArray.prototype.constructor-
建立例項物件的建構函式。
TypedArray.prototype.constructor是隱藏的TypedArray建構函式,但每個型別化陣列子類也定義了自己的constructor屬性。 TypedArray.prototype.length-
返回型別化陣列中包含的元素數量。
TypedArray.prototype[Symbol.toStringTag]-
TypedArray.prototype[Symbol.toStringTag]屬性的初始值是一個 getter,它返回與型別化陣列建構函式名稱相同的字串。如果this值不是型別化陣列子類之一,則返回undefined。此屬性用於Object.prototype.toString()。但是,由於TypedArray也有自己的toString()方法,因此除非你使用型別化陣列作為thisArg呼叫Object.prototype.toString.call(),否則不會使用此屬性。
所有 TypedArray 子類還具有以下例項屬性
TypedArray.prototype.BYTES_PER_ELEMENT-
返回不同
TypedArray物件的元素大小的數字值。
例項方法
這些方法在 TypedArray 原型物件上定義,因此由所有 TypedArray 子類例項共享。
TypedArray.prototype.at()-
接受一個整數值並返回該索引處的項。此方法允許使用負整數,這些整數從最後一項開始倒數。
TypedArray.prototype.copyWithin()-
在陣列內複製一系列陣列元素。另請參見
Array.prototype.copyWithin()。 TypedArray.prototype.entries()-
返回一個新的“陣列迭代器”物件,其中包含陣列中每個索引的鍵/值對。另請參見
Array.prototype.entries()。 TypedArray.prototype.every()-
如果陣列中存在一個不滿足所提供測試函式的元素,則返回
false。否則,返回true。另請參見Array.prototype.every()。 TypedArray.prototype.fill()-
用一個靜態值填充陣列從起始索引到結束索引的所有元素。另請參見
Array.prototype.fill()。 TypedArray.prototype.filter()-
使用此陣列中所有提供過濾函式返回
true的元素建立一個新陣列。另請參見Array.prototype.filter()。 TypedArray.prototype.find()-
返回陣列中滿足提供的測試函式的第一個
element,如果沒有找到合適的元素則返回undefined。另請參見Array.prototype.find()。 TypedArray.prototype.findIndex()-
返回陣列中滿足所提供測試函式的第一個索引值,如果未找到合適的元素則返回
-1。另請參見Array.prototype.findIndex()。 TypedArray.prototype.findLast()-
返回陣列中滿足提供的測試函式的最後一個元素的值,如果沒有找到合適的元素則返回
undefined。另請參見Array.prototype.findLast()。 TypedArray.prototype.findLastIndex()-
返回陣列中滿足提供的測試函式的最後一個元素的索引,如果未找到合適的元素則返回
-1。另請參見Array.prototype.findLastIndex()。 TypedArray.prototype.forEach()-
對陣列中的每個元素呼叫一個函式。另請參見
Array.prototype.forEach()。 TypedArray.prototype.includes()-
確定型別化陣列是否包含某個元素,返回
true或false。另請參見Array.prototype.includes()。 TypedArray.prototype.indexOf()-
返回陣列中等於指定值的元素的第一個(最小)索引,如果沒有找到則返回
-1。另請參見Array.prototype.indexOf()。 TypedArray.prototype.join()-
將陣列的所有元素連線成一個字串。另請參見
Array.prototype.join()。 TypedArray.prototype.keys()-
返回一個新的陣列迭代器,其中包含陣列中每個索引的鍵。另請參見
Array.prototype.keys()。 TypedArray.prototype.lastIndexOf()-
返回陣列中等於指定值的元素的最後一個(最大)索引,如果沒有找到則返回
-1。另請參見Array.prototype.lastIndexOf()。 TypedArray.prototype.map()-
透過對陣列中的每個元素呼叫提供的函式的結果建立一個新陣列。另請參見
Array.prototype.map()。 TypedArray.prototype.reduce()-
對累加器和陣列的每個值(從左到右)應用一個函式,以將其簡化為單個值。另請參見
Array.prototype.reduce()。 TypedArray.prototype.reduceRight()-
對累加器和陣列的每個值(從右到左)應用一個函式,以將其簡化為單個值。另請參見
Array.prototype.reduceRight()。 TypedArray.prototype.reverse()-
反轉陣列元素的順序——第一個變成最後一個,最後一個變成第一個。另請參見
Array.prototype.reverse()。 TypedArray.prototype.set()-
將多個值儲存在型別化陣列中,從指定的陣列讀取輸入值。
TypedArray.prototype.slice()-
提取陣列的一部分並返回一個新陣列。另請參見
Array.prototype.slice()。 TypedArray.prototype.some()-
如果陣列中存在一個滿足所提供測試函式的元素,則返回
true。否則,返回false。另請參見Array.prototype.some()。 TypedArray.prototype.sort()-
對陣列元素進行原地排序並返回陣列。另請參見
Array.prototype.sort()。 TypedArray.prototype.subarray()-
從給定的起始和結束元素索引返回一個新的
TypedArray。 TypedArray.prototype.toLocaleString()-
返回表示陣列及其元素的本地化字串。另請參見
Array.prototype.toLocaleString()。 TypedArray.prototype.toReversed()-
返回一個元素順序反轉的新陣列,而不修改原始陣列。
TypedArray.prototype.toSorted()-
返回一個元素按升序排序的新陣列,而不修改原始陣列。
TypedArray.prototype.toString()-
返回表示陣列及其元素的字串。另請參見
Array.prototype.toString()。 TypedArray.prototype.values()-
返回一個新的“陣列迭代器”物件,其中包含陣列中每個索引的值。另請參見
Array.prototype.values()。 TypedArray.prototype.with()-
返回一個新陣列,其中給定索引處的元素替換為給定值,而不修改原始陣列。
TypedArray.prototype[Symbol.iterator]()-
返回一個新的“陣列迭代器”物件,其中包含陣列中每個索引的值。
示例
屬性訪問
你可以使用標準的陣列索引語法(即使用方括號表示法)引用陣列中的元素。但是,在型別化陣列上獲取或設定索引屬性不會在原型鏈中搜索此屬性,即使索引超出範圍。索引屬性將查詢 ArrayBuffer,並且永遠不會檢視物件屬性。你仍然可以使用命名屬性,就像所有物件一樣。
// Setting and getting using standard array syntax
const int16 = new Int16Array(2);
int16[0] = 42;
console.log(int16[0]); // 42
// Indexed properties on prototypes are not consulted (Fx 25)
Int8Array.prototype[20] = "foo";
new Int8Array(32)[20]; // 0
// even when out of bound
Int8Array.prototype[20] = "foo";
new Int8Array(8)[20]; // undefined
// or with negative integers
Int8Array.prototype[-1] = "foo";
new Int8Array(8)[-1]; // undefined
// Named properties are allowed, though (Fx 30)
Int8Array.prototype.foo = "bar";
new Int8Array(32).foo; // "bar"
不能凍結
非空 TypedArray 不能被凍結,因為它們的底層 ArrayBuffer 可能透過緩衝區的另一個 TypedArray 檢視被修改。這意味著物件永遠不會真正被凍結。
const i8 = Int8Array.of(1, 2, 3);
Object.freeze(i8);
// TypeError: Cannot freeze array buffer views with elements
ByteOffset 必須對齊
將 TypedArray 構造為 ArrayBuffer 的檢視時,byteOffset 引數必須與其元素大小對齊;換句話說,偏移量必須是 BYTES_PER_ELEMENT 的倍數。
const i32 = new Int32Array(new ArrayBuffer(4), 1);
// RangeError: start offset of Int32Array should be a multiple of 4
const i32 = new Int32Array(new ArrayBuffer(4), 0);
ByteLength 必須對齊
與 byteOffset 引數一樣,傳遞給 TypedArray 建構函式的 ArrayBuffer 的 byteLength 屬性必須是建構函式的 BYTES_PER_ELEMENT 的倍數。
const i32 = new Int32Array(new ArrayBuffer(3));
// RangeError: byte length of Int32Array should be a multiple of 4
const i32 = new Int32Array(new ArrayBuffer(4));
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-typedarray-objects |
瀏覽器相容性
載入中…