Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

JavaScript Binary Data: ArrayBuffer, TypedArrays, and DataView

Learn ECMAScript binary data storage and views: ArrayBuffer, TypedArrays, DataView, byte offsets, element conversions, endianness, BigInt views, resizable buffers, and transfer semantics.

Levels: Advanced ~65 min read

Advanced

Interactive Runnable example
Edit

Ready to run.

Quick check

What does an ArrayBuffer provide?

const buffer = new ArrayBuffer(8);
document.querySelector("#output").textContent = `bytes: ${buffer.byteLength}`;
Interactive Runnable example
Edit

Ready to run.

Quick check

What does Uint8Array represent?

const buffer = new ArrayBuffer(4);
const bytes = new Uint8Array(buffer);
bytes[0] = 255;
bytes[1] = 42;
document.querySelector("#output").textContent = [...bytes].join(", ");
Interactive Runnable example
Edit

Ready to run.

Quick check

Why can two TypedArrays observe the same bytes?

const buffer = new ArrayBuffer(4);
const bytes = new Uint8Array(buffer);
const words = new Uint16Array(buffer);
bytes[0] = 0x34; bytes[1] = 0x12;
document.querySelector("#output").textContent = `bytes=${bytes[0]},${bytes[1]}; word=${words[0]}`;
Interactive Runnable example
Edit

Ready to run.

Quick check

What does byteOffset describe?

const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer, 2, 3);
view.fill(7);
document.querySelector("#output").textContent = `${view.byteOffset}/${view.byteLength}/${view.length}`;
Interactive Runnable example
Edit

Ready to run.

Quick check

What happens when values do not fit Uint8Array?

const values = new Uint8Array([1, 257, -1]);
document.querySelector("#output").textContent = [...values].join(", ");
Interactive Runnable example
Edit

Ready to run.

Quick check

What distinguishes Uint8ClampedArray?

const values = new Uint8ClampedArray([1, 300, -4, 12.7]);
document.querySelector("#output").textContent = [...values].join(", ");
Interactive Runnable example
Edit

Ready to run.

Quick check

Which values belong in BigInt64Array?

const values = new BigInt64Array([1n, -2n]);
document.querySelector("#output").textContent = values.join(", ");
Interactive Runnable example
Edit

Ready to run.

Quick check

Why use DataView for binary formats?

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint16(0, 0x1234, true);
const value = view.getUint16(0, true);
document.querySelector("#output").textContent = value.toString(16);
Interactive Runnable example
Edit

Ready to run.

Quick check

What does the littleEndian argument control?

const buffer = new ArrayBuffer(2);
const view = new DataView(buffer);
view.setUint16(0, 0x1234, false);
const big = [...new Uint8Array(buffer)];
view.setUint16(0, 0x1234, true);
const little = [...new Uint8Array(buffer)];
document.querySelector("#output").textContent = `big=${big.join("-")}; little=${little.join("-")}`;
Interactive Runnable example
Edit

Ready to run.

Quick check

Why are BigInt DataView methods useful?

const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setBigUint64(0, 9007199254740993n, true);
document.querySelector("#output").textContent = view.getBigUint64(0, true).toString();
Interactive Runnable example
Edit

Ready to run.

Quick check

How do TypedArrays relate to ordinary array methods?

const values = new Int16Array([10, 20, 30]);
const doubled = values.map(value => value * 2);
document.querySelector("#output").textContent = [...doubled].join(", ");
Interactive Runnable example
Edit

Ready to run.

Quick check

What does copyWithin do?

const values = new Uint8Array([1, 2, 3, 4]);
values.copyWithin(1, 0, 3);
document.querySelector("#output").textContent = [...values].join(", ");
Interactive Runnable example
Edit

Ready to run.

Quick check

What does a resizable ArrayBuffer add?

const buffer = new ArrayBuffer(4, { maxByteLength: 8 });
let result = `before=${buffer.byteLength}`;
if (buffer.resizable) { buffer.resize(6); result += ` after=${buffer.byteLength}`; }
document.querySelector("#output").textContent = result;
Interactive Runnable example
Edit

Ready to run.

Quick check

What happens to the original after ArrayBuffer transfer?

const buffer = new ArrayBuffer(4);
const bytes = new Uint8Array(buffer); bytes[0] = 9;
const moved = buffer.transfer();
document.querySelector("#output").textContent = `old=${buffer.byteLength}; new=${moved.byteLength}; value=${new Uint8Array(moved)[0]}`;
Interactive Runnable example
Edit

Ready to run.

Quick check

What does ArrayBuffer.isView detect?

const buffer = new ArrayBuffer(2);
const bytes = new Uint8Array(buffer);
const view = new DataView(buffer);
document.querySelector("#output").textContent = `${ArrayBuffer.isView(bytes)}/${ArrayBuffer.isView(view)}`;
Interactive Runnable example
Edit

Ready to run.

Quick check

What does the buffer property of a TypedArray expose?

const values = new Uint16Array([1000, 2000]);
console.log(values.buffer.byteLength);

Binary data has layers

An ArrayBuffer supplies raw bytes. TypedArrays interpret those bytes as fixed-width numeric elements, while DataView gives you explicit per-access control over numeric type and byte order. Learning these as separate layers makes binary formats easier to reason about.

TypedArrays are views, not separate storage

A TypedArray normally views an underlying ArrayBuffer. Its byteOffset, byteLength, and element length describe the portion it exposes. Multiple views can share the same bytes, which is useful when a binary format has fields of different widths.

DataView is for format boundaries

Use DataView when a binary protocol specifies fields such as a 16-bit little-endian integer followed by a 32-bit big-endian value. DataView makes the byte order explicit at each read or write instead of forcing one element type across the whole view.

Resizable and transferable buffers

Current ECMAScript also includes resizable ArrayBuffers and ArrayBuffer transfer operations. These change the lifetime and capacity story of binary storage, so code should check the capabilities and semantics it actually needs rather than assuming every buffer is fixed-length.

Author rules

Choose a TypedArray when a region has one consistent element type. Choose DataView when field types or endianness vary. Keep byte offsets and lengths explicit at binary-format boundaries, and use BigInt typed arrays or DataView BigInt methods when exact 64-bit integers exceed Number’s safe-integer range.

Uint8Array.toHex() — bytes to hexadecimal

Uint8Array.prototype.toHex() converts the bytes in the typed array into a hexadecimal String. It is a byte representation operation, not a text-decoding operation.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does Uint8Array.prototype.toHex() return?

const bytes = Uint8Array.from([0, 15, 255]);
document.querySelector("#output").textContent = bytes.toHex();

Uint8Array.fromHex() — hexadecimal to bytes

Uint8Array.fromHex() creates a Uint8Array by decoding a hexadecimal String. The result is binary byte data, so this belongs with TypedArrays rather than the Strings lesson.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does Uint8Array.fromHex() create?

document.querySelector("#output").textContent = [...Uint8Array.fromHex("000fff")].join(", ");

Uint8Array.toBase64() — bytes to Base64

Uint8Array.prototype.toBase64() encodes the typed array's bytes as a Base64 String. The encoding represents bytes; it does not interpret the bytes as Unicode text.

Interactive Runnable example
Edit

Ready to run.

Quick check

What is Uint8Array.prototype.toBase64() for?

const bytes = Uint8Array.from([72, 105]);
document.querySelector("#output").textContent = bytes.toBase64();

Uint8Array.fromBase64() — Base64 to bytes

Uint8Array.fromBase64() decodes a Base64 String into a Uint8Array. The result remains byte data until a separate text-decoding operation is deliberately applied.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does Uint8Array.fromBase64() return?

document.querySelector("#output").textContent = [...Uint8Array.fromBase64("SGk=")].join(", ");

Float16Array and Math.f16round() — binary16 Numbers

Float16Array adds IEEE 754 binary16 storage to the TypedArray family, while Math.f16round() rounds a Number to the nearest representable binary16 value. The APIs belong with the binary-data and numeric representation model, not with general floating-point theory.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does Float16Array add to the TypedArray family?

const array = new Float16Array([1.5]);
document.querySelector("#output").textContent = String(array[0]);
Was this page helpful?

Mark this learning resource complete to track your learning progress.