Docs
README
6.4 TypedArrays and Binary Data
Overview
TypedArrays provide a way to work with raw binary data in JavaScript. They're essential for WebGL, audio processing, file handling, network protocols, and performance-critical applications.
Table of Contents
- β’ArrayBuffer
- β’TypedArray Types
- β’DataView
- β’Working with Binary Data
- β’Use Cases
ArrayBuffer
ArrayBuffer is a fixed-length container for raw binary data. You can't directly manipulate itβyou need views.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ArrayBuffer (16 bytes) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Raw Binary Bytes β
β β
β Views (interpret the same data): β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Uint8Array: [0, 1, 2, 3, 4, 5, 6, 7, ...] 16 elementsβ β
β β Uint16Array: [256, 770, 1284, ...] 8 elements β β
β β Uint32Array: [50462976, ...] 4 elements β β
β β Float64Array: [...] 2 elements β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Creating ArrayBuffer
// Create a 16-byte buffer
const buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); // 16
// Check if something is an ArrayBuffer
console.log(buffer instanceof ArrayBuffer); // true
// Slice a portion (creates new buffer)
const slice = buffer.slice(0, 8); // First 8 bytes
TypedArray Types
| Type | Bytes | Range | Description |
|---|---|---|---|
Int8Array | 1 | -128 to 127 | Signed 8-bit integer |
Uint8Array | 1 | 0 to 255 | Unsigned 8-bit integer |
Uint8ClampedArray | 1 | 0 to 255 | Clamped unsigned 8-bit |
Int16Array | 2 | -32768 to 32767 | Signed 16-bit |
Uint16Array | 2 | 0 to 65535 | Unsigned 16-bit |
Int32Array | 4 | -2Β³ΒΉ to 2Β³ΒΉ-1 | Signed 32-bit |
Uint32Array | 4 | 0 to 2Β³Β²-1 | Unsigned 32-bit |
Float32Array | 4 | Β±3.4E38 | 32-bit float |
Float64Array | 8 | Β±1.8E308 | 64-bit float (double) |
BigInt64Array | 8 | -2βΆΒ³ to 2βΆΒ³-1 | Signed 64-bit BigInt |
BigUint64Array | 8 | 0 to 2βΆβ΄-1 | Unsigned 64-bit BigInt |
Creating TypedArrays
// From length
const uint8 = new Uint8Array(4); // [0, 0, 0, 0]
// From array
const int16 = new Int16Array([1, 2, 3, 4]);
// From another TypedArray
const float32 = new Float32Array(int16);
// From ArrayBuffer
const buffer = new ArrayBuffer(8);
const view1 = new Uint8Array(buffer); // 8 elements
const view2 = new Uint16Array(buffer); // 4 elements
const view3 = new Uint32Array(buffer); // 2 elements
// From ArrayBuffer with offset and length
const partial = new Uint8Array(buffer, 2, 4); // 4 bytes starting at offset 2
TypedArray Properties and Methods
const arr = new Uint8Array([10, 20, 30, 40, 50]);
// Properties
console.log(arr.length); // 5
console.log(arr.byteLength); // 5 (bytes)
console.log(arr.byteOffset); // 0
console.log(arr.buffer); // Underlying ArrayBuffer
console.log(arr.BYTES_PER_ELEMENT); // 1
// Standard array methods work
arr.forEach((x) => console.log(x));
const doubled = arr.map((x) => x * 2);
const filtered = arr.filter((x) => x > 25);
const sum = arr.reduce((a, b) => a + b, 0);
// TypedArray-specific methods
const copy = arr.slice(1, 4); // New TypedArray [20, 30, 40]
arr.set([100, 200], 2); // Set values at index 2
const sub = arr.subarray(1, 4); // View into same buffer
Uint8ClampedArray (for Canvas)
// Regular Uint8Array overflows
const uint8 = new Uint8Array([255]);
uint8[0] = 256;
console.log(uint8[0]); // 0 (overflow!)
// Uint8ClampedArray clamps values
const clamped = new Uint8ClampedArray([255]);
clamped[0] = 256;
console.log(clamped[0]); // 255 (clamped!)
clamped[0] = -10;
console.log(clamped[0]); // 0 (clamped!)
// Used by Canvas ImageData
const imageData = ctx.getImageData(0, 0, 100, 100);
console.log(imageData.data instanceof Uint8ClampedArray); // true
DataView
DataView provides more control over byte order (endianness) and mixed types.
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
// Write values with explicit endianness
view.setInt32(0, 42, true); // Little-endian at offset 0
view.setInt32(4, 42, false); // Big-endian at offset 4
view.setFloat64(8, 3.14159); // Float at offset 8
// Read values
console.log(view.getInt32(0, true)); // 42 (little-endian)
console.log(view.getInt32(4, false)); // 42 (big-endian)
console.log(view.getFloat64(8)); // 3.14159
DataView Methods
// Getters
view.getInt8(offset);
view.getUint8(offset);
view.getInt16(offset, littleEndian);
view.getUint16(offset, littleEndian);
view.getInt32(offset, littleEndian);
view.getUint32(offset, littleEndian);
view.getFloat32(offset, littleEndian);
view.getFloat64(offset, littleEndian);
view.getBigInt64(offset, littleEndian);
view.getBigUint64(offset, littleEndian);
// Setters (same pattern)
view.setInt32(offset, value, littleEndian);
// ... etc
Working with Binary Data
Converting Between Types
// String to bytes
const encoder = new TextEncoder();
const bytes = encoder.encode('Hello'); // Uint8Array
// Bytes to string
const decoder = new TextDecoder();
const str = decoder.decode(bytes); // 'Hello'
// Hex string to bytes
function hexToBytes(hex) {
const bytes = new Uint8Array(hex.length / 2);
for (let i = 0; i < hex.length; i += 2) {
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
}
return bytes;
}
// Bytes to hex string
function bytesToHex(bytes) {
return Array.from(bytes)
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
}
Base64 Encoding
// ArrayBuffer to Base64
function bufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binary = '';
bytes.forEach((b) => (binary += String.fromCharCode(b)));
return btoa(binary);
}
// Base64 to ArrayBuffer
function base64ToBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
Use Cases
1. Canvas Image Manipulation
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data; // Uint8ClampedArray [R,G,B,A, R,G,B,A, ...]
// Invert colors
for (let i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i]; // Red
data[i + 1] = 255 - data[i + 1]; // Green
data[i + 2] = 255 - data[i + 2]; // Blue
// Alpha (i + 3) unchanged
}
ctx.putImageData(imageData, 0, 0);
2. WebSocket Binary Data
const socket = new WebSocket('ws://example.com');
socket.binaryType = 'arraybuffer';
socket.onmessage = (event) => {
const buffer = event.data;
const view = new DataView(buffer);
const messageType = view.getUint8(0);
const payload = new Uint8Array(buffer, 1);
console.log('Type:', messageType, 'Data:', payload);
};
// Send binary data
const buffer = new ArrayBuffer(5);
const view = new DataView(buffer);
view.setUint8(0, 1); // Message type
view.setUint32(1, 12345, true); // Payload
socket.send(buffer);
3. File Reading
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
const file = e.target.files[0];
const buffer = await file.arrayBuffer();
const bytes = new Uint8Array(buffer);
// Check file signature (magic bytes)
const isPNG =
bytes[0] === 0x89 &&
bytes[1] === 0x50 &&
bytes[2] === 0x4e &&
bytes[3] === 0x47;
console.log('Is PNG:', isPNG);
});
4. Audio Processing (Web Audio API)
const audioCtx = new AudioContext();
// Create buffer for 2 seconds of stereo audio
const sampleRate = audioCtx.sampleRate;
const buffer = audioCtx.createBuffer(2, sampleRate * 2, sampleRate);
// Generate sine wave
const channelData = buffer.getChannelData(0); // Float32Array
for (let i = 0; i < channelData.length; i++) {
channelData[i] = Math.sin((2 * Math.PI * 440 * i) / sampleRate);
}
Summary
| Concept | Use Case |
|---|---|
ArrayBuffer | Raw binary data container |
Uint8Array | Byte-level access, files, network |
Uint8ClampedArray | Canvas image data |
Float32Array | Audio, WebGL |
DataView | Mixed types, control endianness |
TextEncoder/Decoder | String β bytes |
Next Steps
- β’Learn about Blob and File APIs for file handling
- β’Explore Web Audio API for audio processing
- β’Study WebGL for 3D graphics