By the end of this lesson, you will be able to read and write binary values at exact byte offsets in an ArrayBuffer using JavaScript DataView.
What it is
A DataView is an object that lets you inspect and modify the bytes inside an ArrayBuffer. An ArrayBuffer is just a fixed-size block of raw memory; it has no type information. A DataView adds a typed view over that memory, so you can say “read a 32-bit signed integer starting at byte 0” or “write an unsigned byte at byte 4.”
Related terms: buffer is the raw bytes, byteOffset is the starting position in bytes, endianness is the order of bytes for multi-byte numbers, and typed arrays such as Uint8Array are another way to view buffers when all elements have the same type.
Why it matters
- It lets you parse binary file formats, network packets, and image headers where fields appear at fixed byte positions.
- It supports mixed data types in one buffer, such as a 32-bit integer followed by a float and a byte flag.
- It gives explicit control over byte order, which is essential when reading data produced by another system.
- It works directly with
ArrayBuffer, which is the common low-level binary container in JavaScript.
Syntax or steps
Create a view over a buffer, then call a getter or setter with a byte offset:
const view = new DataView(buffer, byteOffset, byteLength);
const value = view.getInt32(offset, littleEndian);
view.setUint16(offset, value, littleEndian);
The first constructor argument is required. The second and third are optional and limit the view to part of the buffer. In getters and setters, offset is relative to the start of the view. The optional littleEndian argument is true for little-endian and false or omitted for big-endian.
Example
const buf = new ArrayBuffer(12);
const view = new DataView(buf);
view.setInt32(0, 42, true);
view.setUint8(4, 255);
view.setFloat32(5, 1.5, true);
const id = view.getInt32(0, true);
const flags = view.getUint8(4);
const score = view.getFloat32(5, true);
console.log(id, flags, score); // 42 255 1.5
Part by part:
new ArrayBuffer(12)creates 12 raw bytes.new DataView(buf)creates a view over the whole buffer.setInt32(0, 42, true)writes a signed 32-bit integer at byte 0 using little-endian order.setUint8(4, 255)writes one unsigned byte at byte 4.setFloat32(5, 1.5, true)writes a 32-bit float starting at byte 5.- The getters read the same offsets back, producing the original values.
Common mistakes
- Using element offsets instead of byte offsets.
getInt32(1)starts at byte 1, not at the second 32-bit integer. - Forgetting endianness. If the data was written as little-endian, reading it as big-endian produces a different number.
- Reading past the end of the view. A 32-bit read at byte 10 in a 12-byte buffer is invalid because it needs bytes 10 through 13.
- Choosing
DataViewwhen a typed array is simpler. If every value has the same type and alignment,Uint8ArrayorInt32Arrayis often clearer.
When to use it
| Need | Use | Why |
|---|---|---|
| Mixed types at arbitrary offsets | DataView | It can read int, float, and byte fields from the same buffer. |
| Uniform arrays of numbers | Typed array | It is simpler and often faster for repeated same-type access. |
| Explicit byte-order control | DataView | Getters and setters accept an endianness flag. |
| Direct byte manipulation | Uint8Array | It exposes each byte as an element. |
Practice
Guided exercise: create a 6-byte buffer, write the unsigned 16-bit value 1000 at byte 0 and the signed 8-bit value -5 at byte 2, then read both values back.
const buf = new ArrayBuffer(6);
const view = new DataView(buf);
view.setUint16(0, 1000, true);
view.setInt8(2, -5);
console.log(view.getUint16(0, true), view.getInt8(2)); // 1000 -5
Challenge: write a 32-bit integer at byte 0 and a 16-bit integer at byte 4, then read them back using the same endianness. Hint: use setInt32, setUint16, getInt32, and getUint16.
Quick check
Question: If you call view.getInt32(2, true), what does the 2 mean?
Answer: It means start reading at byte offset 2 from the beginning of the view, not at the third element.
Summary
DataView is the precise JavaScript tool for reading and writing typed values at exact byte positions inside an ArrayBuffer. It is especially useful for binary protocols and file formats where fields have mixed types and fixed offsets. Remember that offsets are bytes, not elements, and that endianness must match the data source.