ArrayBufferView
By Flavio Copes
Learn what an ArrayBufferView is, a portion of an ArrayBuffer with buffer, byteOffset, and byteLength properties, used by typed arrays and DataViews.
An ArrayBufferView is a portion of an ArrayBuffer: a window over its raw bytes, starting at an offset and extending for a length.
Why does it exist? An ArrayBuffer is a block of raw memory. You can’t read or write its bytes directly. You need a view over it, and every view is an ArrayBufferView.
There’s no global ArrayBufferView constructor. You’ll never write new ArrayBufferView(). It’s the common interface shared by typed arrays (like Uint8Array) and DataView objects.
Every view provides 3 read-only properties:
bufferpoints to the original ArrayBufferbyteOffsetis the offset on that bufferbyteLengthis the length of its content in bytes
Let’s create a view over part of a buffer:
const buffer = new ArrayBuffer(16)
const view = new Uint8Array(buffer, 4, 8)
view.buffer === buffer //true
view.byteOffset //4
view.byteLength //8
This view covers 8 bytes of the buffer, starting at byte 4. Reading or writing view[0] touches byte 4 of the underlying buffer.
Views share memory
Views don’t copy data. Several views can sit on the same buffer, and a write through one is visible through the others:
const buffer = new ArrayBuffer(4)
const all = new Uint8Array(buffer)
const tail = new Uint8Array(buffer, 2, 2)
all[2] = 100
tail[0] //100
This is the whole point of views: one chunk of memory, interpreted in different ways, with no copying.
To check if a value is a view over a buffer, use ArrayBuffer.isView():
ArrayBuffer.isView(new Uint8Array(8)) //true
ArrayBuffer.isView(new ArrayBuffer(8)) //false
What happens with a misaligned offset?
Typed arrays require the byte offset to be a multiple of the element size. A Uint32Array element takes 4 bytes, so an offset of 2 throws:
const buffer = new ArrayBuffer(16)
const numbers = new Uint32Array(buffer, 2)
//RangeError: start offset of Uint32Array should be a multiple of 4
You hit this when parsing binary file formats, where fields sit at arbitrary offsets. The fix is a DataView, which reads any type at any offset:
const data = new DataView(buffer)
data.setUint32(2, 500)
data.getUint32(2) //500
That’s the practical split between the two kinds of views. Typed arrays are great when the buffer holds a sequence of same-sized values. DataView is the tool for mixed, unaligned binary data.
Related posts about platform: