UNB/ CS/ David Bremner/ teaching/ cs2613/ books/ mdn/ Reference/ Global Objects/ TypedArray

A TypedArray object describes an array-like view of an underlying binary data buffer. There is no global property named TypedArray, nor is there a directly visible TypedArray constructor. Instead, there are a number of different global properties, whose values are typed array constructors for specific element types, listed below. On the following pages you will find common properties and methods that can be used with any typed array containing elements of any type.

Description

The TypedArray constructor (often referred to as %TypedArray% to indicate its "intrinsicness", since it does not correspond to any global exposed to a JavaScript program) serves as the common superclass of all TypedArray subclasses. Think about %TypedArray% as an "abstract class" providing a common interface of utility methods for all typed array subclasses. This constructor is not directly exposed: there is no global TypedArray property. It is only accessible through Object.getPrototypeOf(Int8Array) and similar.

When creating an instance of a TypedArray subclass (e.g. Int8Array), an array buffer is created internally in memory or, if an ArrayBuffer object is given as constructor argument, that ArrayBuffer is used instead. The buffer address is saved as an internal property of the instance and all the methods of %TypedArray%.prototype will set and get values based on that array buffer address.

TypedArray objects

Type Value Range Size in bytes Web IDL type
Int8Array -128 to 127 1 byte
Uint8Array 0 to 255 1 octet
Uint8ClampedArray 0 to 255 1 octet
Int16Array -32768 to 32767 2 short
Uint16Array 0 to 65535 2 unsigned short
Int32Array -2147483648 to 2147483647 4 long
Uint32Array 0 to 4294967295 4 unsigned long
Float32Array -3.4e38 to 3.4e38 4 unrestricted float
Float64Array -1.8e308 to 1.8e308 8 unrestricted double
BigInt64Array -263 to 263 - 1 8 bigint
BigUint64Array 0 to 264 - 1 8 bigint

Value encoding and normalization

All typed arrays operate on ArrayBuffers, where you can observe the exact byte representation of each element, so how the numbers are encoded in binary format is significant.

All typed arrays except Int8Array, Uint8Array, and Uint8ClampedArray store each element using multiple bytes. These bytes can either be ordered from most significant to least significant (big-endian) or from least significant to most significant (little-endian). See Endianness for more explanation. Typed arrays always use the platform's native byte order. If you want to specify the endianness when writing and reading from buffers, you should use a DataView instead.

When writing to these typed arrays, values that are outside the representable range are normalized.

Behavior when viewing a resizable buffer

When a TypedArray is created as a view of a resizable buffer, resizing the underlying buffer will have different effects on the size of the TypedArray depending on whether the TypedArray is constructed as length-tracking.

If a typed array is created without a specific size by omitting the third parameter or passing undefined, the typed array will become length-tracking, and will automatically resize to fit the underlying buffer as the latter is resized:

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

If a typed array is created with a specific size using the third length parameter, it won't resize to contain the buffer as the latter is grown:

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

When a buffer is shrunk, the viewing typed array may become out of bounds, in which case the typed array's observed size will decrease to 0. This is the only case where a non-length-tracking typed array's length may change.

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

If you then grow the buffer again to bring the typed array back in bounds, the typed array's size will be restored to its original value.

buffer.resize(8);

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

The same can happen for length-tracking typed arrays as well, if the buffer is shrunk beyond the 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

Constructor

This object cannot be instantiated directly — attempting to construct it with new throws a TypeError.

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

Instead, you create an instance of a typed array of a particular type, such as an Int8Array or a BigInt64Array. These objects all have a common syntax for their constructors:

new TypedArray()
new TypedArray(length)
new TypedArray(typedArray)
new TypedArray(object)

new TypedArray(buffer)
new TypedArray(buffer, byteOffset)
new TypedArray(buffer, byteOffset, length)

Where TypedArray is a constructor for one of the concrete types.

Note: All TypedArray subclasses' constructors can only be constructed with new. Attempting to call one without new throws a TypeError.

Parameters

Exceptions

All TypeArray subclass constructors operate in the same way. They would all throw the following exceptions:

Static properties

These properties are defined on the TypedArray constructor object and are thus shared by all TypedArray subclass constructors.

All TypedArray subclasses also have the following static properties:

Static methods

These methods are defined on the TypedArray constructor object and are thus shared by all TypedArray subclass constructors.

Instance properties

These properties are defined on TypedArray.prototype and shared by all TypedArray subclass instances.

All TypedArray subclasses also have the following instance properties:

Instance methods

These methods are defined on the TypedArray prototype object and are thus shared by all TypedArray subclass instances.

Examples

Property access

You can reference elements in the array using standard array index syntax (that is, using bracket notation). However, getting or setting indexed properties on typed arrays will not search in the prototype chain for this property, even when the indices are out of bound. Indexed properties will consult the ArrayBuffer and will never look at object properties. You can still use named properties, just like with all objects.

// 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"

Cannot be frozen

TypedArrays that aren't empty cannot be frozen, as their underlying ArrayBuffer could be mutated through another TypedArray view of the buffer. This would mean that the object would never genuinely be frozen.

const i8 = Int8Array.of(1, 2, 3);
Object.freeze(i8);
// TypeError: Cannot freeze array buffer views with elements

ByteOffset must be aligned

When constructing a TypedArray as a view onto an ArrayBuffer, the byteOffset argument must be aligned to its element size; in other words, the offset must be a multiple of 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 must be aligned

Like the byteOffset parameter, the byteLength property of an ArrayBuffer passed to a TypedArray's constructor must be a multiple of the constructor's 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));

Specifications

Browser compatibility

See also