Understand the comparison and use of arraybuffer, typedarray and DataView

Make a little progress every day 2021-09-15 09:45:25

A picture shows

To illustrate their relationship , I drew a picture , Where the arrow does not represent a containment relationship , It's the relationship from the bottom to the top , We will explain it later



ArrayBuffer Object represents a piece of memory that stores binary data , It's an array of bytes .

It cannot be read or written directly , Need to create View To operate on it , Views can manipulate binary data in a specified format .

ArrayBuffer It's also a constructor , You can use it to create contiguous memory areas , The parameter is the memory size ( Unit byte ), The default initial values are 0

const buf = new ArrayBuffer(32)
 Copy code 


ArrayBuffer You need to operate through the view , Views can take two forms : Typed array (TypedArray) perhaps DataView,TypeArray Reading and writing 11 A specific type of binary data ,DataView Used to read and write binary data of custom composite types

Let's introduce

Typed array (TypedArray)

TypeArray yes ArrayBuffer A binary data operation view , actually , There is no name TypeArray Global variable of , It's not called TypeArray Constructor for , I think it can be understood as a 11 A collection of views of a particular type , Is a general designation .

this 11 Two specific types of views are ( Excerpt from MDN):

type The range of individual element values size (bytes) describe Web IDL type C Equivalent types in languages
Int8Array -128 to 127 1 8 Bit binary signed integer byte int8_t
Uint8Array 0 to 255 1 8 Bit unsigned integer ( Loop from another boundary when out of range ) octet uint8_t
Uint8ClampedArray 0 to 255 1 8 Bit unsigned integer ( Beyond the range, it is the boundary value ) octet uint8_t
Int16Array -32768 to 32767 2 16 Bit binary signed integer short int16_t
Uint16Array 0 to 65535 2 16 Bit unsigned integer unsigned short uint16_t
Int32Array -2147483648 to 2147483647 4 32 Bit binary signed integer long int32_t
Uint32Array 0 to 4294967295 4 32 Bit unsigned integer unsigned long uint32_t
Float32Array 1.2×10-38 to 3.4×1038 4 32 position IEEE Floating point numbers (7 Significant digits , Such as  1.1234567 unrestricted float float
Float64Array 5.0×10-324 to 1.8×10308 8 64 position IEEE Floating point numbers (16 Significant figures , Such as  1.123...15) unrestricted double double
BigInt64Array -263 to 263-1 8 64 Bit binary signed integer bigint int64_t (signed long long)
BigUint64Array 0 to 264-1 8 64 Bit unsigned integer bigint uint64_t (unsigned long long)

They are all constructors , The array generated by these constructors , Similar to an ordinary array , You can use all array methods , The difference between them and ordinary arrays is :

  1. TypeArray Elements are of one type
  2. TypeArray Elements are continuous , There will be no vacant seats
  3. TypeArray The initial values of pattern elements are 0
  4. TypeArray Just a layer view , The data is stored at the bottom ArrayBuffer in

that , How to use these views to ArrayBuffer To operate ?

const typeArray = new Int8Array(8);
typeArray[0] = 32;
console.log(typeArray); // [32, 0, 0, 0, 0, 0, 0, 0]
const typeArray1 = new Int8Array(typeArray);
typeArray1[1] = 42;
console.log(typeArray1); // [32, 42, 0, 0, 0, 0, 0, 0]
 Copy code 

Here are all kinds of TypeArray Examples of constructor usage , Note that this is just the syntax format , In actual use, it needs to be replaced with various constructors .

// The following code is the syntax format , Can't run directly ,
// TypedArray Keywords need to be replaced with various constructors .
new TypedArray(); // ES2017 Newly added 
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);
 Copy code 

If we were ArrayBuffer If you create a new view on

// Generate 8 Bytes of memory 
const buf = new ArrayBuffer(8);
const int8Array = new Int8Array(buf, 0);
int8Array[3] = 32;
const int16Array = new Int16Array(buf, 0, 4);
int16Array[0] = 42;
console.log(int16Array); // [42, 8192, 0, 0] Because the third byte is set to 32, So when you use two bytes to represent an integer , It becomes 00010000 00000000, That is to say 2 Of 13 Power ,8192
console.log(int8Array); // [42, 0, 0, 32, 0, 0, 0, 0]
 Copy code 

This is what we can see , Use int8 and int16 The new views created by the two methods affect each other , Are directly modified at the bottom buffer The data of , They just operate on the bottom buffer Two views of data .

in addition , Operation method of ordinary array , Yes TypeArray Also fully applicable . Compared to ordinary arrays TypeArray The biggest advantage of is that you can directly manipulate memory , in addition , No data type conversion is required , So the speed is much faster .


If a piece of data includes multiple types ( For example, from the server http data ), Except that it can be set separately TypeArray Start byte and length , You can also use DataView To make a custom composite view .

In the initial design ArrayBuffer Of TypedArray View , It is used to send data to the network card 、 Sound card and other local devices transmit data ;DataView It is used to process data from network devices , It also supports setting byte order ( I'll talk about it later )

DataView It's also a constructor itself

new DataView(ArrayBuffer buffer [, Byte start position [, length ]]);
 Copy code 

for instance :

const buf = new ArrayBuffer(24);
const dataview = new DataView(buf);
 Copy code 

This creates a new DataView View ,DataView Examples provide 10 There are two ways to read and write memory

You can see MDN:developer.mozilla.org/en-US/docs/…

With DataView.prototype.getInt8() For example

 Copy code 

Express DataView The example starts from byteOffset Byte start , Read a signed 8bit Integers ( A byte ), Continue with the previous example :

const buf = new ArrayBuffer(24);
const dataview = new DataView(buf);
dataview.setInt8(1, 3);
dataview.getInt8(1); // 3
 Copy code 

This is how to use different methods on examples , Read and write memory

Here you may think , If through different types of TypeArray, Specify the start byte and length , The same effect can be achieved , Well, now look, yes , however DataView There is another feature : Set byte order , Let's move on to the next chapter

Byte order

What is byte order

First, let's talk about what byte order is , Byte order is how values are stored in memory . It is divided into small end byte order (little-endian) And big endian byte order (big-endian) Two kinds of

All Intel processors use small endian byte order , Our personal computers are basically small endian , Small endian will put the least important first , It can be compared with the common date writing method in Europe ( for example ,31 December 2050. The year is the most important , Next month , Date last )

The big endian byte order is the opposite order , Analogical ISO Date format ( for example 2050-12-31).big-endian Usually called " Network byte order "("network byte order"), Because Internet standards usually require the use of data big-endian Storage , From the standard Unix Socket (socket) Layer start , Up to the binary data structure of the standardized network .

Byte order and TypedArray、DataView The relationship between

TypedArray in , The byte order will follow the byte order of the system , So they are basically small end byte order , It does not support self setting , Then there will be a problem : If the data requested from the network is big endian , Will cause the data to be unable to parse .

by comparison ,DataView Can support setting byte order , for instance :

const buffer = new ArrayBuffer(24);
const dv = new DataView(buffer);
// Small endian byte order 
const v1 = dv.getUint16(1, true);
// Big endian byte order 
const v2 = dv.getUint16(3, false);
// Big endian byte order 
const v3 = dv.getUint16(3);
 Copy code 

DataView The second parameter of the instance method , Can be used to set byte order , The default is big endian

If you are not sure about the byte order on the computer , You can judge by this method :

const littleEndian = (function() {
const buffer = new ArrayBuffer(2);
new DataView(buffer).setInt16(0, 256, true);
return new Int16Array(buffer)[0] === 256;
 Copy code 

If you return true, Small endian byte order ; If you return false, It's big endian .

For details of this part, please refer to :es6.ruanyifeng.com/#docs/array…

Reference resources




Byte order :developer.mozilla.org/zh-CN/docs/…

Please bring the original link to reprint ,thank
Similar articles