04. Typed Arrays
Типизированные массивы в ES6 используются для работы с бинарными данными, а так же для взаимодействия с нативными API, использующими бинарные данные. С развитием веба появилось все больше API, работающих с бинарными данными.
File API
XMLHttpRequest
Fetch API
Canvas
WebSockets
WebGL
Аудио/Видео
В Typed Array API используется две разновидности объектов:
Типизированные массивы (
Uint8Array,Int16Array,Float32Array, etc.) интерпретируют содержимоеArrayBufferкак индексированную последовательность элементов заданного типа.Объекты
DataViewпозволяют получать доступ к содержимомуArrayBufferкак к элементам одного из числовых типов (Uint8,Int16,Float32, etc.) с определенной размерностью.
ArrayBuffers store the data, views (Typed Arrays and DataView) let you read and change it. In order to create a DataView, you need to provide its constructor with an ArrayBuffer. Typed Array constructors can optionally create an ArrayBuffer for you.
ArrayBuffer
ArrayBufferОбъект ArrayBuffer это стандартный набор бинарных данных с фиксированной длинной. Вы не можете манипулировать содержимым ArrayBuffer напрямую. Вместо этого, необходимо создать типизованное представление DataView, которое будет отображать буфер в определенном формате, и даст доступ на запись и чтение его содержимого.
// 16 bytes array buffer
const buffer = new ArrayBuffer(16);
// we can have multiple views on the top of buffer
const int32View = new Int32Array(buffer);
const int16View = new Int16Array(buffer);Setting up Typed Array.
При создании типизированного массива вызывается его конструктор в котором указывается число байт:
// Typed array views work pretty much like normal arrays.
var f64a = new Float64Array(8);
f64a[0] = 10;
f64a[1] = 20;
f64a[2] = f64a[0] + f64a[1];Статический метод ArrayBuffer.isView(obj) принимает на вход obj в проверяет, является ли он ArrayBuffer или его представлением.
Если необходимо создать Typed Array из набора значений, то стоит использовать функцию TypedArray.of(...items), играющей роль статического конструктора.
Float32Array.of(0.151, -8, 3.7);Аналогично массивам, существует метод TypedArray<U>.from(source : Iterable<T>, mapfn? : T => U, thisArg?) конвертирующий данные из итерируемого источника в новый объект типизированного массива
const ui16 = Uint16Array.from(Uint8Array.of(0, 1, 2));Typed Arrays and regular Arrays
Типизированные массивы хоть и берут многое от массивов, технически ими не являются.
Сходства:
У Typed Array есть поле
length.Доступ к элементам Typed Array осуществляется по индексу в квадратных скобках
[...].У них есть все методы, свойственные массивам.
Вызов
Arrays.isArray()вернетfalseдля типизированных массивов.Типизированные массивы являются итерируемыми.
Различия:
Индекс элемента может быть отрицательным
Все элементы типизированных массивов имеют один тип.
Типизированные массивы являются непрерывными и не имеют дыр.
Имеют поле
buffer, ссылающееся на оригинальный буфер, представлением которого является данный типизированный массив.
Byte Data
Типизированные массивы накладывают ограничения на значения своих элементов в диапазоне (в соответствии с типом). Для всех типизированных массивов, за исключением UInt8ClampedArray переполнение обрабатывается по обычным правилам:
При переполнении в большую сторону, значение переходит в минимальное для данного диапазона
При переполнении в меньшую сторону, значение переходит в большее для данного диапазона
const uint8 = new Uint8Array(1);
uint8[0] = 255;
uint8[0]; // highest value within range
255;
uint8[0] = 256;
uint8[0]; // overflow
0;Для UInt8ClampedArray выходящие за диапазон сбрасываются к своим соответствующим верхним/нижним границам.
Для типов данных, чья размерность превышает один байт начинает играть роль порядок байт. Для типизированных массивов используется порядок байт той платформы на которой они были созданы и не может быть измен в дальнейшем.
DataView
DataViewОбъект DataView это низкоуровневый интерфейс предоставляющий API для записи/чтения произвольных данных в буфер. Это полезно при работе с разнородными данными, например. В то время как типизованные представления всегда имеют порядок байт родной для вашей операционной системы, DataView позволяет контролировать порядок байт (byte-order). По умолчанию этоbig-endian, но через API можно установить little-endian.
Объекты DataView создаются при помощи следующего конструктора DataView(buffer, byteOffset=0, byteLength=buffer.byteLength-byteOffset) на основе существующего буфера.
Объекты DataView представляют read/write api для чтения данных из буфера. Два основных метода:
getElementType(byteOffset, littleEndian=false)- читает данные в виде одного из типов.setElementType(byteOffset, value, littleEndian=false)- записывает данные в виде одного из типов.Где
ElementTypeэто один изFloat32,Float64,Int8,Int16,Int32,Uint8,Uint16,Uint32
const dv = new DataView(buffer);
const vector_length = dv.getUint8(0);
const width = dv.getUint16(1); // 0+uint8 = 1 bytes offset
const height = dv.getUint16(3); // 0+uint8+uint16 = 3 bytes offset
const vectors = new Float32Array(width * height * vector_length);
for (const i = 0, off = 5; i < vectors.length; i++, off += 4) {
vectors[i] = dv.getFloat32(off);
}Для объектов DataView можно контролировать порядок байт, указывая его в методах доступа/чтения. По умолчанию используется BigEndian.
Объекты DataView могут использоваться для гетерогенных данных.
References
Last updated
Was this helpful?