Otra de las novedades que incorpora ECMAScript 2015 (popularmente conocido como ES6) es la de vectores tipados (Typed arrays en inglés).
Estos objetos son del tipo Array y nos proporcionan un mecanismo para acceder a datos binarios puros, lo que nos puede ayudar a la hora de manipular directamente datos crudos de audio o vídeo, trabajar con WebSockets, etc.
Los vectores tipados no deben confundirse con vectores normales: la llamada Array.isArray() en un typed array devuelve false. Del mismo modo, algunos métodos de arrays normales, no están disponibles en los typed arrays, como push o pop.
Arquitectura de los typed arrays
Los typed arrays separan su implementación en 2 elementos:
- buffer: (objeto ArrayBuffer) Es el objeto que representa un segmento de datos de tamaño fijo, sin un formato de referencia ni mecanismo de acceso a su contenido.
-
vistas: La vista proporciona un contexto (tipo de dato, desplazamiento y número de elementos) para obtener los datos en un vector tipado real.
La siguiente imagen de la documentación de Mozilla Foundation nos permite entender mejor la relación entre buffers y vistas
Como vemos, el ArrayBuffer es un buffer de dimensión fija donde se almacenan los datos binarios, mientras que Uint8Array, Uint16Array, etc. son vistas de vectores tipados para diferentes tipos numéricos (o contextos), es decir, definen de qué modo deben agruparse los bytes de su buffer a la hora de acceder a ellos.
Tipos de vistas
Para leer y escribir el contenido de un ArrayBuffer, creas una vista de vector tipado o bien una DataView que represente el buffer en un formato específico.
Vistas de vector tipado
Las vistas de vector tipado tienen nombres autodescriptivos, y proporcionan contextos para los tipos numéricos más habituales.
Cabe destacar el Uint8ClampedArray, que restringe los valores entre 0 y 255 (util para procesar imágenes, como datos de Canvas, por ejemplo).
Type | Size in bytes | Description | Web IDL type |
---|---|---|---|
Int8Array | 1 | 8-bit two’s complement signed integer | byte |
Uint8Array | 1 | 8-bit unsigned integer | octet |
Uint8ClampedArray | 1 | 8-bit unsigned integer (clamped) | octet |
Int16Array | 2 | 16-bit two’s complement signed integer | short |
Uint16Array | 2 | 16-bit unsigned integer | unsigned short |
Int32Array | 4 | 32-bit two’s complement signed integer | long |
Uint32Array | 4 | 32-bit unsigned integer | unsigned long |
Float32Array | 4 | 32-bit IEEE floating point number | unrestricted float |
Float64Array | 8 | 64-bit IEEE floating point number | unrestricted double |
DataView
Un DataView es una interface de bajo nivel que proporciona una API getter/setter para leer y escribir datos en el buffer de forma arbitraria.
Una de las ventajas que nos ofrece un DataView, es que puedes controlar el orden de los bytes, lo que permite modificar los getters/setters para pasar de big-endian (por defecto) a little-endian, por ejemplo.
Las vistas de vector tipado están en la Endianness de tu plataforma, mientras que el en DataView, se trabaja por defecto en big-endian.
Trabajando con Typed Arrays
A continuación, un ejemplo de como trabajar con typed Arrays mediante vistas de vector tipado, a partir de un ArrayBuffer:
let buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); //16
//necesitamos una vista para poder leer/escribir del buffer. Creamos una vista de 4 bytes por elemento
var int32View = new Int32Array(buffer);
//Inicializamos cada elemento de la vista
for (var i = 0; i < int32View.length; i++) {
int32View[i] = 3-i;
}
//el buffer contiene los valores [3, 2, 1, 0]
for(let item of int32View){
console.log(item);
}//3, 2, 1, 0
No obstante, podemos inicializar directamente una vista de vector tipado a partir de un array tradicional:
let typedArray = new Uint8Array([0,1,2]);
console.log(typedArray.length); // 3
typedArray[0] = 5;
for(let item of typedArray){
console.log(item);
}//5, 1, 2
let normalArray = [...typedArray]; // [5,1,2]
Y así es como trabajaríamos con un DataView:
let typedArray = new Uint8Array([0,1,2]);
//Obtenemos un buffer, ya sea a través de ArrayBuffer, o mediante una vista de vector tipado
let dataView = new DataView(typedArray.buffer);
//definimos cómo queremos acceder al contenido
console.log(dataView.getUint8(0)); // 5
Conclusiones
Los typed arrays nos facilitan el acceso a datos binarios, lo cual puede ser muy util de cara a trabajar con imágenes, o manipulando ficheros en el dispositivo, ya sea una aplicación en local o estemos trabajando en la parte de servidor con Node.js.
En la documentación de Mozilla Foundation para vectores tipados puedes encontrar más detalles.
¡¡Saludos!!
Be First to Comment