Modern JavaScript is faced with more complex scenarios and more data transfers of various types, including binary transfers. ArrayBuffer objects were created to facilitate processing of data and improve efficiency.

ArrayBuffer, DataView, Blob, FileReader, etc. Why are there so many objects? I looked up the data with the question and tried to sort out the relationship.

Relationships between various objects

ArrayBuffer

An ArrayBuffer is JavaScript’s most basic binary processing object, which describes a contiguous memory space in bytes.

const buffer = new ArrayBuffer(32);
Copy the code

This creates a 32-byte memory area whose length can be viewed using buffer.bytelength.

An ArrayBuffer object does not do much and is not editable. If you need to edit the data, use the other two objects TypedArray and DataView.

TypedArray

TypedArray is a TypedArray. TypedArray itself does not store any data, but is used exclusively to view ArrayBuffer data.

  • Int8Array: 1 bit, 8 bit signed integer

  • Uint8Array: 1 bit, 8 bit unsigned integer

  • Uint8ClampedArray: 1 bit, 8 bits unsigned integer

  • Int16Array: a 2-bit, 16-bit unsigned integer

  • Uint16Array: 2 bits, 16 bits unsigned integer

  • Int32Array: a 4-bit, 32-bit unsigned integer

  • Uint32Array: 4 bits, 32 bits unsigned integer

  • Float32Array: 4 bits, 32 bits None IEEE floating point number

  • Float64Array: 8 bits, 64 bits none IEEE floating point number

  • BigInt64Array: 8 bits. 64 is a binary signed integer

  • BigUint64Array: 8-bit, 64-bit unsigned integer

You can pass in length, typedArray, ArrayBuffer, and array. Or you can pass in nothing.

const uint1 = new Uint8Array(8);
const uint2 = new Uint16Array(new Uint8Array(8));
const uint3 = new Uint8Array(new ArrayBuffer(8));
const uint4 = new Uint8Array([1, 2, 3]);
const uint5 = new Uint8Array();
Copy the code

In the above typedArray, a new ArrayBuffer is created at the bottom of the new process, except when an ArrayBuffer is passed in during creation. You can use arr.buffer to access the ArrayBuffer it references.

Operations on ordinary arrays can be used in TypedArray. But because ArrayBuffer describes a contiguous memory interval, we cannot delete a value and can only allocate 0, nor can we use concat method.

Uint8ClampedArray

Uint8ClampedArray is relatively special, it is handled differently in the case of positive and negative overflow.

In other cases, only the right-most (low) part is reserved for the data stored out of bounds and the overflow data is discarded, while the Uint8ClampedArray saves 255 for the data stored out of bounds and 0 for the negative numbers passed in.

Character to character conversion

TypedArray does not pass strings directly, so you need to transcode them first.

The String – Unit8Array

 const string = "Hello";
Uint8Array.from(string.split(""), (e) => e.charCodeAt(0));
Copy the code

Unit8Array – > String

Const u8 = uint8array. of(72, 101, 108, 108, 111); new TextDecoder().decode(u8); Const u8 = uint8array. of(72, 101, 108, 108, 111); Array.from(u8, (e) => String.fromCharCode(e)).join("");Copy the code

DataView

The above data are all single data types except uint2 variable. The uint2 object, which is a piece of memory, stores two types of data, which is called composite view. Data types in JavaScript tend to be less monolithic, and using TypedArray alone would be more cumbersome, so DataView objects were introduced. DataView has more options than TypedArray.

const buffer = new ArrayBuffer(8);
const dataView = new DataView(buffer);
Copy the code

The getInt8, getUint8, getInt16, getUint16, getInt32, getUint32, getFloat32, and getFloat64 methods are provided.

The first is the byte order and the second is the byte order, which is not required. The return value is the byte of data at the corresponding location.

const d1 = dataView.getUint8(1);
const d2 = dataView.getUint8(1, true);
Copy the code

Byte positions are easy to understand, and byte ordering can be read in Understanding byte ordering. In summary:

  • Big endian: The way humans read and write numbers is that the most important byte is first and the least important byte is second.

  • Little endian: The lowest byte is first and the highest byte is last, which is stored as 0x1122.

By default, big-endian order is used, and true is required to use small-endian order.

So we have a basic binary read/write scheme. However, real application scenarios tend to have more complex data, so objects such as BLObs and FileReader are derived for specific scenarios.

Blob

Blob, short for Binary Large Object.

Unlike an ArrayBuffer, which is pure binary data, a Blob is binary data with MIME type. And can be easily generated from String, ArrayBuffer, TypedArray, DataView, Blob into Blob objects.

const blob1 = new Blob(["hello"], { type: "text/plain" });
const blob2 = new Blob([new Uint8Array([72, 101, 108, 108, 111]), " ", "world"], { type: "text/plain" });
Copy the code

Properties:

  • Size: The byte size of the read object.

  • Type: Reads the MIME type to be written

Methods:

  • sliceExtract:BlobFragment.

URL

In development we get image binary data, which we can convert to base64 and write to SRC, but if the data is very large, or video data, it will exceed its allowable length. We can easily create a resource URL using url.createObjecturl.

const url = URL.createObjectURL(blob1);
Copy the code

Generates a similar blob:https://example.com/a6728d20-2e78-4497-9d6c-0ed61b93f11e resource URL, which can be directly used in writing the SRC.

RevokeObjectURL (URL) destroys its reference when not in use, freeing its memory usage.

Data is read

If we want to look at the data, there are two ways.

First, with Response objects, you can read string data or arrayBuffer data directly.

const responseText = await new Response(blob2).text();
const responseBuf = await new Response(blob2).arrayBuffer();
Copy the code

Second, use the FileReader object.

const reader = new FileReader();
reader.onload = function (e) {
    console.log(reader.result);
};
reader.readAsText(blob2);
Copy the code

File

File inherits from Blob and adds file-related attribute information.

  • Name: File name

  • LastModified: timestamp of the lastModified time

  • LastModifiedDate: Date object whose time was last modified

  • WebkitRelativePath: the path of the file. This property is set when selecting a directory in input, a non-standard feature.

FileList

A FileList object is a collection of File objects. Generally appears in:

  • control, where the files property is a FileList

  • DataTransfer object generated in the drag event, where the files property will be a FileList

Properties:

  • length: Can get the currentFileListHow manyFile

Methods:

  • item(index): retrieves the specified index locationFileData, generally used directlyFileList[index]The alternative.

FileReader

As mentioned in the Blob section, FileReader objects are actually designed to read Blob objects, including extended File objects.

Properties:

  • Result: Indicates the file content.

  • ReadyState: indicates the status. 0: not loaded. 1: loading. 2: Loading is complete.

  • Error: Indicates an error message when loading data.

Events:

  • Onload: Triggered after the load succeeds.

  • Onerror: Triggered when loading errors occur.

  • Onabort: Triggered when loading interrupts.

  • Onloadend: Triggered after loading ends.

  • Onloadstart: triggered when the load starts.

  • Onprogress: triggered while loading.

Methods:

  • ReadAsText (blob, “UTF-8 “) : Returns data as text, with text encoding as the second argument.

  • ReadAsDataURL (BLOB) : Returns Data as a DataURL.

  • ReadAsArrayBuffer (BLOB) : Returns data as an ArrayBuffer.

  • Abort: Aborts an operation.

In the example above, the data is returned as text:

const reader = new FileReader();
reader.onload = function (e) {
    console.log(reader.result);
};
reader.readAsText(blob2);
Copy the code

The relevant data

MDN related keywords

Modern JavaScript tutorial Part 3 Binary data, files

Ruan Yifeng JavaScript tutorial browser model related chapters