JavaScript Typed Arrays
TypedArray objects in JavaScript provide a mechanism for accessing raw binary data in memory buffers. They're used when working with binary streams, WebGL, or performance-critical applications.
Unlike regular arrays, typed arrays are strongly typed and store data in a contiguous memory region using specific data types (e.g., 8-bit integers or 32-bit floats).
Quick Links
Creating Typed Arrays in JavaScript
In JavaScript, typed arrays are arrays with a fixed size and a specific data type (such as integers or floating-point numbers). These arrays are different from regular JavaScript arrays, which can store any type of data and can grow or shrink in size. Typed arrays help to handle binary data efficiently and are especially useful when working with large datasets, such as in web APIs or when processing images and files.
1. From a Given Length
You can create a typed array by specifying how many elements it should have. By default, all elements in the array will be initialized to 0
.
const intArray = new Int16Array(4); // Creates an array with 4 elements, all set to 0
console.log(intArray); // Output: Int16Array(4) [0, 0, 0, 0]
const intArray = new Int16Array(4); // Creates an array with 4 elements, all set to 0
console.log(intArray); // Output: Int16Array(4) [0, 0, 0, 0]
In the above example, we created an Int16Array
with 4 elements. The array is filled with zeroes since no initial values were provided.
2. From a Regular Array
You can also create a typed array by passing a regular JavaScript array. The values in the regular array will be converted to the appropriate type for the typed array.
const floatArray = new Float32Array([1.5, 2.5, 3.5]); // Create a Float32Array from a regular array
console.log(floatArray); // Output: Float32Array(3) [1.5, 2.5, 3.5]
const floatArray = new Float32Array([1.5, 2.5, 3.5]); // Create a Float32Array from a regular array
console.log(floatArray); // Output: Float32Array(3) [1.5, 2.5, 3.5]
In this example, we create a Float32Array
from a regular array of numbers. The typed array retains the values as floating-point numbers.
3. From Another TypedArray
You can create a new typed array from an existing one, even if the types are different. The values will be copied and converted to the new type.
const source = new Uint8Array([10, 20, 30]); // Create a Uint8Array with 3 values
const copy = new Int16Array(source); // Create a new Int16Array from the source
console.log(copy); // Output: Int16Array(3) [10, 20, 30]
const source = new Uint8Array([10, 20, 30]); // Create a Uint8Array with 3 values
const copy = new Int16Array(source); // Create a new Int16Array from the source
console.log(copy); // Output: Int16Array(3) [10, 20, 30]
Here, we create a Uint8Array
with three values and then create a new Int16Array
from it. The values are copied and converted to the Int16Array
type without changing their actual values.
4. From an ArrayBuffer
All typed arrays are backed by an ArrayBuffer
, which is a generic storage object for raw binary data. You can create a typed array that views this buffer.
const buffer = new ArrayBuffer(8); // Create an ArrayBuffer with 8 bytes (8 values of 1 byte each)
const view = new Uint32Array(buffer); // Create a view (typed array) over the ArrayBuffer
console.log(view); // Output: Uint32Array(2) [0, 0]
const buffer = new ArrayBuffer(8); // Create an ArrayBuffer with 8 bytes (8 values of 1 byte each)
const view = new Uint32Array(buffer); // Create a view (typed array) over the ArrayBuffer
console.log(view); // Output: Uint32Array(2) [0, 0]
In the example above, we create an ArrayBuffer
of 8 bytes. Then, we create a Uint32Array
view on this buffer. Since the buffer is 8 bytes, this means that we can fit 2 elements of 4 bytes (32 bits) in the buffer, and both elements are initialized to 0.
5. Using Byte Offset and Length
You can also create a typed array from a subset of an ArrayBuffer
. By specifying a byte offset and the number of elements, you can create a view that only accesses part of the buffer.
const buffer = new ArrayBuffer(16); // Create an ArrayBuffer with 16 bytes
const view = new Uint16Array(buffer, 4, 4); // Start at byte 4 and take 4 elements (2 bytes each)
console.log(view.length); // Output: 4
const buffer = new ArrayBuffer(16); // Create an ArrayBuffer with 16 bytes
const view = new Uint16Array(buffer, 4, 4); // Start at byte 4 and take 4 elements (2 bytes each)
console.log(view.length); // Output: 4
In this case, we created a new ArrayBuffer
of 16 bytes and then created a Uint16Array
starting at byte 4, with 4 elements. Each element in this typed array takes 2 bytes (16 bits), so we can view the next 4 elements of the buffer.
Accessing and Modifying Typed Array Elements
Just like regular JavaScript arrays, typed arrays use zero-based indexing. This means you can access or modify elements using the index in square bracket notation. Additionally, you can loop through elements with different methods.
1. Accessing by Index
To access elements, you simply refer to the index of the element using square bracket notation.
const intArray = new Int16Array([10, 20, 30]);
console.log(intArray[0]); // Output: 10 (First element)
console.log(intArray[2]); // Output: 30 (Third element)
const intArray = new Int16Array([10, 20, 30]);
console.log(intArray[0]); // Output: 10 (First element)
console.log(intArray[2]); // Output: 30 (Third element)
In this example, we access the first and third elements of the typed array using their respective indices (0 and 2). Typed arrays work just like regular arrays when it comes to indexing.
2. Modifying an Element
You can modify the values of typed arrays by directly assigning a new value to a specific index.
const intArray = new Int16Array([10, 20, 30]);
intArray[1] = 99; // Modifies the second element
console.log(intArray); // Output: Int16Array(3) [10, 99, 30]
const intArray = new Int16Array([10, 20, 30]);
intArray[1] = 99; // Modifies the second element
console.log(intArray); // Output: Int16Array(3) [10, 99, 30]
In this case, we change the second element (index 1) from 20
to 99
. The update is reflected when we log the array.
3. Looping with for
You can use a standard for
loop to iterate through each element in a typed array, just like with regular arrays.
const floatArray = new Float32Array([1.0, 2.0, 3.0]);
for (let i = 0; i < floatArray.length; i++) {
console.log(floatArray[i]);
}
// Output:
// 1
// 2
// 3
const floatArray = new Float32Array([1.0, 2.0, 3.0]);
for (let i = 0; i < floatArray.length; i++) {
console.log(floatArray[i]);
}
// Output:
// 1
// 2
// 3
In this example, we use a for
loop to print each element of the Float32Array
. We loop through the array using its length and access each element by index.
4. Looping with for...of
Typed arrays are iterable, meaning you can use the for...of
loop for a more concise and readable iteration over the array's elements.
const uintArray = new Uint8Array([100, 200, 255]);
for (const value of uintArray) {
console.log(value);
}
// Output:
// 100
// 200
// 255
const uintArray = new Uint8Array([100, 200, 255]);
for (const value of uintArray) {
console.log(value);
}
// Output:
// 100
// 200
// 255
Here, the for...of
loop is used to iterate directly over the values in the typed array, making the code shorter and easier to read.
5. Using map()
The map()
method can be used on typed arrays to transform each element, but it returns a regular JavaScript array, not a typed array.
const intArray = new Int8Array([1, 2, 3]);
const doubled = intArray.map(x => x * 2); // Doubles each element
console.log(doubled); // Output: [2, 4, 6]
const intArray = new Int8Array([1, 2, 3]);
const doubled = intArray.map(x => x * 2); // Doubles each element
console.log(doubled); // Output: [2, 4, 6]
In this case, we use map()
to double each value in the typed array. However, note that the result is a regular JavaScript array, not a typed array.
6. Handling Out-of-Bounds Access
If you try to access an index that is outside the bounds of the array, it will return undefined
. Also, if you attempt to assign a value to an out-of-bounds index, it won't have any effect since typed arrays cannot grow in size.
const arr = new Uint8Array([5, 10, 15]);
console.log(arr[5]); // Output: undefined (Index 5 is out of bounds)
arr[5] = 99; // No effect, array size doesn't change
console.log(arr); // Output: Uint8Array(3) [5, 10, 15]
const arr = new Uint8Array([5, 10, 15]);
console.log(arr[5]); // Output: undefined (Index 5 is out of bounds)
arr[5] = 99; // No effect, array size doesn't change
console.log(arr); // Output: Uint8Array(3) [5, 10, 15]
In this example, trying to access an element at index 5 returns undefined
because the array only has three elements. Similarly, assigning a value to index 5 has no effect, as the typed array cannot grow beyond its initial size.
Modifying Typed Arrays
Typed arrays have a fixed length and are typed buffers, meaning you cannot change their size once created. However, you can modify the values within them using various techniques. Below are some common methods for modifying elements in a typed array.
1. Updating Elements by Index
You can directly modify elements in a typed array by specifying their index in square brackets.
const arr = new Uint8Array([10, 20, 30]);
arr[1] = 99; // Update the second element
console.log(arr); // Output: Uint8Array(3) [10, 99, 30]
const arr = new Uint8Array([10, 20, 30]);
arr[1] = 99; // Update the second element
console.log(arr); // Output: Uint8Array(3) [10, 99, 30]
In this example, we modify the second element (at index 1) of the typed array from 20
to 99
. The change is reflected immediately in the array.
2. Using fill()
The fill()
method allows you to overwrite all or a specific part of the array with a given value. You can also specify a start and end index to limit the modification to a portion of the array.
const arr = new Int16Array(5);
arr.fill(7); // Fill the entire array with 7
console.log(arr); // Output: Int16Array(5) [7, 7, 7, 7, 7]
arr.fill(2, 1, 4); // Fill only from index 1 to index 3 with 2
console.log(arr); // Output: Int16Array(5) [7, 2, 2, 2, 7]
const arr = new Int16Array(5);
arr.fill(7); // Fill the entire array with 7
console.log(arr); // Output: Int16Array(5) [7, 7, 7, 7, 7]
arr.fill(2, 1, 4); // Fill only from index 1 to index 3 with 2
console.log(arr); // Output: Int16Array(5) [7, 2, 2, 2, 7]
In the first example, we fill the entire Int16Array
with the value 7
. In the second example, we fill part of the array (from index 1 to index 3) with the value 2
.
3. Using set() to Copy Data
The set()
method is used to copy values from another array (either typed or regular) into an existing typed array.
const target = new Uint8Array(5);
const source = [100, 200];
target.set(source, 1); // Copy values from the source array starting at index 1
console.log(target); // Output: Uint8Array(5) [0, 100, 200, 0, 0]
const target = new Uint8Array(5);
const source = [100, 200];
target.set(source, 1); // Copy values from the source array starting at index 1
console.log(target); // Output: Uint8Array(5) [0, 100, 200, 0, 0]
In this example, we use set()
to copy the values from the source
array into the target
typed array, starting at index 1. The initial zeros are left unchanged, while the copied values replace the values at indices 1 and 2.
4. Using map() to Create a New Modified Array
The map()
method creates a new array (a regular array, not a typed array) by applying a function to each element of the typed array.
const original = new Uint16Array([1, 2, 3]);
const squared = original.map(x => x * x); // Square each element
console.log(squared); // Output: [1, 4, 9]
const original = new Uint16Array([1, 2, 3]);
const squared = original.map(x => x * x); // Square each element
console.log(squared); // Output: [1, 4, 9]
Here, we use map()
to square each element of the typed array. The result is a regular array, not a typed array, which holds the squared values.
5. In-Place Updates with Loops
If you want to update elements in place (without creating a new array), you can use a loop, such as a for
loop.
const arr = new Float32Array([1.5, 2.5, 3.5]);
for (let i = 0; i < arr.length; i++) {
arr[i] *= 2; // Double each element
}
console.log(arr); // Output: Float32Array(3) [3, 5, 7]
const arr = new Float32Array([1.5, 2.5, 3.5]);
for (let i = 0; i < arr.length; i++) {
arr[i] *= 2; // Double each element
}
console.log(arr); // Output: Float32Array(3) [3, 5, 7]
In this example, we loop through the Float32Array
and multiply each element by 2
. This directly modifies the values of the array without creating a new array.
Typed Array Methods
Typed arrays in JavaScript support many familiar methods similar to regular arrays. However, some methods—like push() and splice()—are not available because typed arrays have a fixed length.
1. slice()
Returns a shallow copy of a portion of a typed array into a new typed array.
const arr = new Uint8Array([10, 20, 30, 40]);
const sliced = arr.slice(1, 3);
console.log(sliced); // Output: Uint8Array(2) [20, 30]
const arr = new Uint8Array([10, 20, 30, 40]);
const sliced = arr.slice(1, 3);
console.log(sliced); // Output: Uint8Array(2) [20, 30]
2. subarray()
Similar to slice(), but returns a view over the same underlying buffer.
const arr = new Int16Array([100, 200, 300, 400]);
const view = arr.subarray(1, 3);
console.log(view); // Output: Int16Array(2) [200, 300]
const arr = new Int16Array([100, 200, 300, 400]);
const view = arr.subarray(1, 3);
console.log(view); // Output: Int16Array(2) [200, 300]
3. set()
Copies values from another array (typed or regular) into the current array starting at a given index.
const target = new Uint8Array(4);
target.set([1, 2], 1);
console.log(target); // Output: Uint8Array(4) [0, 1, 2, 0]
const target = new Uint8Array(4);
target.set([1, 2], 1);
console.log(target); // Output: Uint8Array(4) [0, 1, 2, 0]
4. map()
Applies a function to each element and returns a new regular array.
const arr = new Uint8Array([1, 2, 3]);
const result = arr.map(x => x * 10);
console.log(result); // Output: [10, 20, 30]
const arr = new Uint8Array([1, 2, 3]);
const result = arr.map(x => x * 10);
console.log(result); // Output: [10, 20, 30]
5. forEach()
Executes a function for each element in the typed array.
const arr = new Float64Array([1.1, 2.2, 3.3]);
arr.forEach(value => {
console.log(value);
});
// Output:
// 1.1
// 2.2
// 3.3
const arr = new Float64Array([1.1, 2.2, 3.3]);
arr.forEach(value => {
console.log(value);
});
// Output:
// 1.1
// 2.2
// 3.3
6. includes()
Checks if the array contains a specified value.
const arr = new Int8Array([-1, 0, 1]);
console.log(arr.includes(0)); // Output: true
console.log(arr.includes(5)); // Output: false
const arr = new Int8Array([-1, 0, 1]);
console.log(arr.includes(0)); // Output: true
console.log(arr.includes(5)); // Output: false
7. indexOf()
Returns the first index at which a given value is found, or -1 if not found.
const arr = new Uint8Array([5, 10, 15]);
console.log(arr.indexOf(10)); // Output: 1
console.log(arr.indexOf(99)); // Output: -1
const arr = new Uint8Array([5, 10, 15]);
console.log(arr.indexOf(10)); // Output: 1
console.log(arr.indexOf(99)); // Output: -1
Frequently Asked Questions
What are Typed Arrays in JavaScript?
What are Typed Arrays in JavaScript?
Typed Arrays are arrays that provide a way to handle binary data in a structured manner. They work with ArrayBuffers and include specific types like Int8Array, Uint16Array, and Float32Array.
How do you create a Typed Array in JavaScript?
How do you create a Typed Array in JavaScript?
Create a Typed Array by passing an ArrayBuffer to the constructor, like this: let intArray = new Int8Array(5); or by using a specific buffer: let floatArray = new Float32Array(buffer);.
What is the difference between Typed Arrays and regular JavaScript Arrays?
What is the difference between Typed Arrays and regular JavaScript Arrays?
Typed Arrays are used to handle binary data with a fixed size and specific type. They are optimized for performance and are used when working with raw data. Regular JavaScript Arrays are more flexible and can hold any type of data.
Can Typed Arrays store any data type?
Can Typed Arrays store any data type?
No, Typed Arrays can only store numeric values (e.g., integers, floats) and are optimized for performance. They can't store non-numeric data types like strings or objects.
How do you manipulate data in a Typed Array?
How do you manipulate data in a Typed Array?
You can manipulate a Typed Array using methods like set(), slice(), or forEach(). However, keep in mind that Typed Arrays have fixed lengths and types.
What's Next?
Up next: Learning more about strings in JavaScript—how to work with text in useful and fun ways.