TypedArray

Baseline 廣泛可用 *

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

* 此特性的某些部分可能存在不同級別的支援。

一個 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 -6550465504 2 N/A
Float32Array -3.4e383.4e38 4 unrestricted float
Float64Array -1.8e3081.8e308 8 無限制雙精度
BigInt64Array -263 到 263 - 1 8 bigint
BigUint64Array 0 到 264 - 1 8 bigint

值編碼和規範化

所有型別化陣列都在 ArrayBuffer 上操作,你可以在其中觀察每個元素的精確位元組表示,因此數字在二進位制格式中的編碼方式非常重要。

  • 無符號整數陣列(Uint8ArrayUint16ArrayUint32ArrayBigUint64Array)直接以二進位制形式儲存數字。
  • 有符號整數陣列(Int8ArrayInt16ArrayInt32ArrayBigInt64Array)使用二進位制補碼儲存數字。
  • 浮點陣列(Float16ArrayFloat32ArrayFloat64Array)使用IEEE 754 浮點格式儲存數字。Number 引用中有關於精確格式的更多資訊。JavaScript 數字預設使用雙精度浮點格式,這與 Float64Array 相同。Float32Array 使用 23 位(而不是 52 位)表示尾數,8 位(而不是 11 位)表示指數。Float16Array 使用 10 位表示尾數,5 位表示指數。請注意,規範要求所有NaN 值使用相同的位編碼,但確切的位模式取決於實現。
  • Uint8ClampedArray 是一個特殊情況。它像 Uint8Array 一樣以二進位制形式儲存數字,但是當儲存超出範圍的數字時,它會透過數學值將數字“鉗制”到 0 到 255 的範圍,而不是截斷最高有效位。

Int8ArrayUint8ArrayUint8ClampedArray 之外的所有型別化陣列都使用多個位元組儲存每個元素。這些位元組可以從最高有效到最低有效(大端序)或從最低有效到最高有效(小端序)排序。有關更多說明,請參閱位元組序。型別化陣列始終使用平臺的本機位元組序。如果要在從緩衝區寫入和讀取時指定位元組序,則應改用 DataView

寫入這些型別化陣列時,超出可表示範圍的值將進行規範化。

  • 所有整數陣列(Uint8ClampedArray 除外)都使用固定寬度數字轉換,它首先截斷數字的小數部分,然後取最低位。
  • Uint8ClampedArray 首先將數字鉗制到 0 到 255 的範圍(大於 255 的值變為 255,小於 0 的值變為 0)。然後它將結果“四捨五入”(而不是向下取整)到最接近的整數,採用半舍到偶數;這意味著如果數字恰好介於兩個整數之間,它將四捨五入到最接近的偶數整數。例如,0.5 變為 01.5 變為 22.5 變為 2
  • Float16ArrayFloat32Array 執行“四捨五入到偶數”以將 64 位浮點數轉換為 32 位和 16 位。這與 Math.fround()Math.f16round() 提供的演算法相同。

檢視可調整大小的緩衝區時的行為

TypedArray 作為可調整大小的緩衝區的檢視建立時,調整底層緩衝區的大小將對 TypedArray 的大小產生不同的影響,具體取決於 TypedArray 是否被構造為長度跟蹤。

如果建立型別化陣列時未指定特定大小(透過省略第三個引數或傳遞 undefined),則型別化陣列將變為“長度跟蹤”,並且會隨著底層 buffer 的調整大小而自動調整以適應它。

js
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

js
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。這是非長度跟蹤型別化陣列長度可能改變的唯一情況。

js
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 以使型別化陣列回到界限內,則型別化陣列的大小將恢復到其原始值。

js
buffer.resize(8);

console.log(float32.byteLength); // 8
console.log(float32.length); // 2
console.log(float32[0]); // 0 - back in bounds again!

如果緩衝區縮小到 byteOffset 之外,長度跟蹤型別化陣列也可能發生同樣的情況。

js
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

js
new (Object.getPrototypeOf(Int8Array))();
// TypeError: Abstract class TypedArray not directly constructable

相反,你建立特定型別的型別化陣列例項,例如 Int8ArrayBigInt64Array。這些物件都有一個共同的建構函式語法。

js
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 子類的建構函式都只能透過 new 來構造。嘗試在沒有 new 的情況下呼叫其中一個會丟擲 TypeError

引數

typedArray

當使用 TypedArray 子類的例項呼叫時,typedArray 會被複制到一個新的型別化陣列中。對於非 bigint TypedArray 建構函式,typedArray 引數只能是以下非 bigint 型別之一(例如 Int32Array)。類似地,對於 bigint TypedArray 建構函式(BigInt64ArrayBigUint64Array),typedArray 引數只能是以下 bigint 型別之一。typedArray 中的每個值在複製到新陣列之前都會轉換為建構函式的相應型別。新型別化陣列的長度將與 typedArray 引數的長度相同。

object

當使用非 TypedArray 例項的物件呼叫時,將以與 TypedArray.from() 方法相同的方式建立一個新的型別化陣列。

length 可選

當使用非物件呼叫時,引數將被視為指定型別化陣列長度的數字。記憶體中會建立一個內部陣列緩衝區,大小為 length 乘以 BYTES_PER_ELEMENT 位元組,並用零填充。省略所有引數等同於使用 0 作為 length

bufferbyteOffset 可選length 可選

當使用 ArrayBufferSharedArrayBuffer 例項呼叫時,以及可選的 byteOffsetlength 引數,將建立一個新的型別化陣列檢視來檢視指定的緩衝區。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()

確定型別化陣列是否包含某個元素,返回 truefalse。另請參見 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,並且永遠不會檢視物件屬性。你仍然可以使用命名屬性,就像所有物件一樣。

js
// 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 檢視被修改。這意味著物件永遠不會真正被凍結。

js
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 的倍數。

js
const i32 = new Int32Array(new ArrayBuffer(4), 1);
// RangeError: start offset of Int32Array should be a multiple of 4
js
const i32 = new Int32Array(new ArrayBuffer(4), 0);

ByteLength 必須對齊

byteOffset 引數一樣,傳遞給 TypedArray 建構函式的 ArrayBufferbyteLength 屬性必須是建構函式的 BYTES_PER_ELEMENT 的倍數。

js
const i32 = new Int32Array(new ArrayBuffer(3));
// RangeError: byte length of Int32Array should be a multiple of 4
js
const i32 = new Int32Array(new ArrayBuffer(4));

規範

規範
ECMAScript® 2026 語言規範
# sec-typedarray-objects

瀏覽器相容性

另見