ES6 Stereotypes Array

Source: Internet
Author: User
Tags arithmetic

Previous words

The training array is a dedicated array for processing numeric types (as its name, not all types) of data, originally used in WebGL, a ported version of OpenGL ES 2.0, which is presented in a Web page through the <canvas> element. The stereotypes array is also ported together, which provides a fast bitwise operation for JS. This article describes the ES6 training array in detail

Overview

In JS, numbers are stored in 64-bit floating-point format and converted to 32-bit integers on demand, so arithmetic operations are slow enough to meet the needs of WEBGL. Therefore, the training arrays are introduced in ES6 to solve this problem and provide higher performance arithmetic operations. The so-called training array, is to convert any number into an array containing a number of bits, then you can use our familiar JS array method to further processing

ES6 uses a trained array as the official format of the language to ensure better compatibility across JS engines and interoperability with JS arrays. Although the ES6 version of the training array is not the same as in WebGL, it retains enough similarities, which allows the ES6 version to evolve based on the WebGL version without going into full differentiation

"Numeric data type"

JS numbers are stored in the format defined by the IEEE 754 standard, which means that 64 bits are used to store a number in a floating-point form. This format is used to represent integers and floating-point numbers in JS, and the two formats are often accompanied by digital changes that convert to each other. The training array supports storing and manipulating the following 8 different numeric types

Signed 8-bit integer (int8) unsigned 8-bit integer (UINT8) signed 16-bit integer (int16) unsigned 16-bit integer (uint16) signed 32-bit integer (int32) unsigned 32-bit integer (UInt32) 32-bit floating-point number (float32) 64-bit floating point number (float64)

Storing 8-bit integers with ordinary JS numbers would waste a full 56 bits that could have stored other 8-bit integers or numbers less than 56 bits. This is also an actual use case of the stereotypes array, i.e. more efficient use of bits

All operations and objects related to the training array are concentrated on these 8 data types, but before using them, you need to create an array buffer to store the data

"Array Buffers"

An array buffer is the foundation of all training arrays, which is a memory address that can contain a specific number of bytes. The process of creating an array buffer is similar to calling malloc () in the C language to allocate memory, but does not need to indicate the type of data the memory block contains. Array buffers can be created by Arraybuffer constructors

Let buffer = New ArrayBuffer (10)//allocated 10 bytes

The number of bits that should pass in the array buffer when the constructor is called, and this statement in this example creates an array buffer of 10 bytes in length. Once created, the number of bits in the buffer can be viewed through the ByteLength property

Let buffer = new ArrayBuffer (10); 10 bytes of Console.log (buffer.bytelength) allocated; 10

The slice () method can be used to split an existing array buffer to create a new one, and the slice () method is much like the slice () method on the array: passing in the start and end indexes as parameters, and then returning a new Arraybuffer instance. The new instance is made up of slices of the original array buffer

Let buffer = new ArrayBuffer (10); 10 bytes Allocated Let Buffer2 = Buffer.slice (4, 6); Console.log (buffer2.bytelength); 2

In this code, Buffer2 creates bytes extracted from index 4 and index 5, where the call to the slice () method is similar to the array version, and the second parameter passed in is not included in the final result

Of course, just creating a storage unit is not very useful, unless you can write data to that cell, and you need to create a view to implement the Write function

[note] The actual number of bytes contained in the array buffer is determined at the time of creation, and the data within the buffer can be modified, but the size of the buffer cannot be changed

View Actions

An array buffer is an address in memory where the view is the interface used to manipulate memory. A view can manipulate a subset of array buffers or buffer bytes and read and write data according to one of the numeric data types. The DataView type is a common array buffer view that supports all 8 numeric data types

To use DataView, you first create a Arraybuffer instance, and then use this instance to create a new DataView

Let buffer = new ArrayBuffer (ten),    view = new DataView (buffer);

In this example, the View object can access all 10 bytes in the buffer. If you provide a numeric value that represents a bit offset, you can create a view based on a portion of the buffer, and DataView will select all the bits from the offset value to the end of the buffer by default. If you provide an optional parameter that represents the number of selected bits, DataView selects the number of bits from the offset position

Let buffer = new ArrayBuffer,    view = new DataView (buffer, 5, 2);//byte containing position 5 and position 6

The view here can only manipulate bytes at index 5 and index 6. This way, you can create multiple view based on the same array buffer, so you can request a whole block of independent memory addresses for your application, rather than allocating them dynamically when space is needed

"Get View Information"

You can obtain information about a view by using the following read-only properties

Buffer View-bound array buffer byteoffset The second parameter of the DataView constructor, which is 0 by default, only has a value when the parameter is passed bytelength the third parameter of the DataView constructor, which defaults to the length of the buffer bytelength

These properties allow you to see which part of the buffer the view is manipulating

Let buffer = new ArrayBuffer (ten), View1 = new DataView (buffer),//contains all bytes View2 = new DataView (buffer, 5, 2); BYTE console.log containing position 5 and position 6 (view1.buffer = = = buffer); Trueconsole.log (View2.buffer = = = buffer); Trueconsole.log (View1.byteoffset); 0console.log (View2.byteoffset); 5console.log (view1.bytelength); 10console.log (view2.bytelength); 2

This code creates a total of two views, view1 covers the entire array buffer, VIEW2 only a small part of the operation. Because these views are created from the same array buffers, they have the same buffer property, but the Byteoffset and ByteLength properties of each view are different, and the values of the two properties depend on which part of the view Operation array Buffer

Of course, reading information from memory is not very useful, it requires both reading and writing data in memory to make the most of it.

"Read and Write Data"

JS has 8 numeric data types, and for each of these, it is possible to find the corresponding method of writing data and reading data in the array buffer on the DataView prototype. These method names begin with a set or get, followed by an abbreviation for each data type. For example, the following list is a method for reading and writing int8 and UNIT8 type data

GetInt8 (Byteoffset,littleendian) reads int8 type data after Byteoffset setInt8 (byteoffset, Value, Littleendian) in Byteoffset Write int8 type data getUint8 (Byteoffset, Littleendian) reads Byteoffset type data uint8 (setUint8, Value, Byteoffset) after Littleendian Write uint8 type data at Byteoffset

The Get method accepts two parameters: the number of bytes offset at the time the data is read and an optional Boolean value that indicates whether to read in small order (the small-endian is the byte order in bytes 0 of the least significant bytes). The Set method accepts three parameters: the number of bits to offset when writing the data, the value to write, and an optional Boolean value that indicates whether it is stored in a small-endian format. Although only the methods used for 8-bit values are shown here, there are some of the same methods that can be used to manipulate 16 or 32-bit values, just by replacing 8 in each method name with 16 or 32. In addition to all integer methods, the DataView also supports the following methods for reading and writing floating-point numbers

GetFloat32 (Byteoffset, Littleendian) reads float32 type data setFloat32 (Byteoffset,value,littleendian) after Byteoffset Write float32 type Data GetFloat64 (Byteoffset,littleendian) at Byteoffset to read Byteoffset type data float64 after SetFloat64 (Byteoffset, Value,littleendian) write float64 type data at Byteoffset

The following example shows the actual use of the set and get methods, respectively

Let buffer = new ArrayBuffer (2),    view = new DataView (buffer), view.setint8 (0, 5); View.setint8 (1,-1); Console.log ( View.getint8 (0)); 5console.log (View.getint8 (1)); -1

This code uses a two-byte array buffer to store the values of two int8 types, at offsets 0 and 1, each of which spans an entire byte (8 bits) followed by the Getlnt8 () method to extract the values from their location.

Views are independent and can read or write data in any format at any time, regardless of how the data was stored before. For example, write a value of two int8 types, and then use the Int16 type method to read the values from the buffer.

Let buffer = new ArrayBuffer (2),    view = new DataView (buffer), view.setint8 (0, 5); View.setint8 (1,-1); Console.log ( View.getint16 (0)); 1535console.log (view.getint8 (0)); 5console.log (View.getint8 (1)); -1

When you call View.getint16 (0), all the bytes in the view are read and interpreted as the number 1535. As shown below, the array buffers are changed after the SetInt8 () method of each row is executed, so you can understand why this result is obtained

New ArrayBuffer (2)   0000000000000000view.setint8 (0, 5);  0000010100000000view.setint8 (1,-1); 0000010111111111

At first, the array buffers all 16 bits of the value is 0, through the SetInt8 () method to write the number 5 to the first byte, where two digits 0 will become the number 1 (8 bit represents 5 is 00000101) will-1 write to the second byte, all bits will become 1, This is also the 1 binary complement representation. After the first call to SetInt8 (), the array buffers contain a total of 16 bits, and getInt16 () reads the bits as a 16-bit integer number, which is the decimal 1535

The DataView object is a perfect choice when mixed with different data types, however, a particular type of view is a better choice if only one particular data type is used

"Train array is view"

The ES6 stereotypes array is actually a specific type of view for an array buffer, and you can force a specific data type instead of using a generic DataView object to manipulate the array buffers. 8 Specific types of views correspond to 8 numeric data types, and uint8 values have other options

The Constructor Name column lists the constructors for several training arrays, and the other columns describe the data that each training array can contain. Uint8clampedarray is roughly the same as Uint8array, except that the value in the array buffer is less than 0 or greater than 255,uint8clampedarray is converted to 0 or 255, for example, 1 will become 0,300 and 255

The train array operation can only be performed on a specific data type, for example, all Int8array operations use a value of type int8. The dimensions of the elements in the training array also depend on the type of the array, the elements in the Int8array take one byte, and each element in the Float64array occupies 8 bytes. Fortunately, the element can be accessed as a normal array via a numeric index, thus avoiding embarrassing scenes when calling DataView's set and get methods

"Create a specific type of view"

The train array constructor can accept multiple types of parameters, so you can create training arrays in several ways. First, you can pass in parameters that are acceptable to the DataView constructor to create a new training array, which is an array buffer, an optional bit offset, and an optional length value

Let buffer = new ArrayBuffer (ten),    view1 = new Int8array (buffer),    view2 = new Int8array (buffer, 5, 2); Console.log (v Iew1.buffer = = = buffer); Trueconsole.log (View2.buffer = = = buffer); Trueconsole.log (View1.byteoffset); 0console.log (View2.byteoffset); 5console.log (view1.bytelength); 10console.log (view2.bytelength); 2

In this code, two views are Int8array instances generated through buffer, View1 and view2 have the same buffer, Byteoffset, and ByteLength properties, and DataView instances contain these three properties. When you use DataView, it's always easy to switch to the appropriate training array whenever you want to handle only one numeric type

The second way to create a training array is to pass in a number when the constructor is called. This number represents the number of elements allocated to the array (not the number of bits), the constructor creates a new buffer and allocates a reasonable number of bits according to the number of elements in the array, and the length property provides access to the number of elements in the array

Let ints = new Int16array (2),    floats = new Float32array (5); Console.log (ints.bytelength);//4console.log ( Ints.length); 2console.log (floats.bytelength); 20console.log (floats.length); 5

The ints array is created with two empty elements, each 16-bit integer value requires two bytes, and 4 bytes are allocated to the array, and the floats array is created with 5 empty elements, each with 4 bytes, so a total of 20 bytes is required. In both cases, if you want to access the newly created buffer, you can use the Buffer property to implement the

[note] When calling the constructor of the train array, if the parameter is not passed, it is treated as passed in, so that the training array created cannot be used to hold the data because the buffer is not assigned to any bits

The third way to create a training array is to pass in any of the following objects as unique parameters when you call the constructor

1, a training array

Each element in the array is copied into the new training array as a new element. For example, if you pass an int8 array into the Int16array constructor, the value of int8 is copied into a new int16 array, and the new training array uses the new array buffer

2. An object that can be iterated

An iterator to an object is called to pick the element that is inserted into the training array by retrieving all the entries, and if all the elements are not valid for that type of view, the constructor throws an error

3, an array

The elements in the array are copied into a new training array, and if all the elements are not valid for the type of the view, the constructor throws an error

4. An array object of a class

Consistent with the behavior of incoming arrays

In each example, the data for the newly created training array is taken from the source object, which is especially useful when initializing the training array with some values

Let ints1 = new Int16array ([+]),    ints2 = new Int32array (ints1); Console.log (Ints1.buffer = = = Ints2.buffer);//FAL Seconsole.log (ints1.bytelength); 4console.log (ints1.length); 2console.log (Ints1[0]); 25console.log (ints1[1]); 50console.log (ints2.bytelength); 8console.log (ints2.length); 2console.log (Ints2[0]); 25console.log (ints2[1]); 50

In this example, a int16array is created and initialized with an array of two values, and then a int32arpay is created with Int16array as a parameter, and since the buffers for the two training arrays are completely independent, the values 25 and 50 are copied from Ints1 to Ints2. There are the same numbers in the two training arrays, except that Ints2 uses 8 bytes to represent the data, while Ints1 only uses 4 bytes

Same point

There are several similarities between a trained array and an ordinary array, and in many cases you can use the training array in the same way as normal arrays. For example, you can view the number of elements in the training array by using the Length property, and you can access the elements in the training array directly through a numeric index

Let ints = new Int16array ([+]); Console.log (ints.length); 2console.log (Ints[0]); 25console.log (Ints[1]); 50ints[0] = 1;ints[1] = 2;console.log (ints[0]); 1console.log (Ints[1]); 2

In this code, the newly created Int16array has two elements, all of which are read and written by a numeric index, and those values are automatically stored and converted to Int16 type values. Of course, there are other similarities between training arrays and normal arrays.

[note] The length property can be modified to change the size of the normal array, and the length property of the training array is a non-writable property, so the size of the training array cannot be modified, if you attempt to modify this value, the operation will be ignored directly in strict mode and an error will be thrown

"Common Method"

The training array also includes many methods that are functionally equivalent to normal array methods, and the following methods are available for training arrays

Copywithin () entries () Fill () filter () find () FindIndex () ForEach () indexOf () join () keys () lastIndexOf () map () reduce () Reduceright () reverse () slice () some () sort () values ()

Although these methods are similar to those in Array.prototype, they are not fully consistent, the methods in the training array will be extra checked for the safety of the numeric type, and the return value of the method will be confirmed by Symbol.species as the training array instead of the normal array

Let ints = new Int16array ([+]),    mapped = ints.map (v = v * 2); Console.log (mapped.length);//2console.log (MAPP Ed[0]); 50console.log (mapped[1]); 100console.log (mapped instanceof Int16array); True

This code uses the map () method to create a new array that holds integers, and the map () method multiplies each value in the array by 2, and finally returns an array of the new Int16array type.

"Same Iterator"

The training array has 3 identical iterators to the normal array, namely the entries () method, the keys () method, and the values () method, which means that the training array can be treated as a normal array using the expand Operator, for-of Loop

Let ints = new Int16array ([+]),    Intsarray = [... ints];console.log (Intsarray instanceof Array);//Trueconsole.lo G (Intsarray[0]); 25console.log (intsarray[1]); 50

This code creates a new array named Intsarray that contains the same data as the training array ints. The expand operator can convert an iterative object to a normal array, or it can convert a training array to a normal array

"Of () method and from () method"

All training arrays contain the static of () method and the From () method, respectively, similar to the Array.of () method and the Array.from () method, except that the method of the training array returns the training array, whereas the normal array method returns a normal array

Let INTs = Int16array.of (+),    floats = Float32array.from ([1.5, 2.5]); Console.log (ints instanceof Int16array);// Trueconsole.log (floats instanceof Float32array); Trueconsole.log (ints.length); 2console.log (Ints[0]); 25console.log (Ints[1]); 50console.log (floats.length); 2console.log (Floats[0]); 1.5console.log (Floats[1]); 2.5

In this example, the of () method and the From () method create Int16array and Float32array respectively, which ensures that the creation of the training array is as simple as a normal array

Different points

The most important difference between a trained array and an ordinary array is that the training array is not an ordinary array. It does not inherit from the array, and the Array.isarray () method is used to check that the training array returns false

Let ints = new Int16array ([+]); Console.log (ints instanceof Array); Falseconsole.log (Array.isarray (ints)); False

Because the variable ints is an array of stereotypes, it is neither an instance of an array nor is it a known one. It is important to make this distinction, because although the training arrays are similar to normal arrays, they behave differently in many ways

"Behavioral Differences"

When you manipulate an ordinary array, it can become larger and smaller, but the training array remains the same size. Assigning values to numeric indexes that do not exist in the training array is ignored, and in a normal array you can

Let ints = new Int16array ([+]); Console.log (ints.length); 2console.log (Ints[0]); 25console.log (Ints[1]); 50INTS[2] = 5;console.log (ints.length); 2console.log (ints[2]); Undefined

In this example, although the numeric index 2 is assigned a value of 5, the ints array size does not grow, the assignment is discarded, and the length property remains unchanged

The training array also checks the legitimacy of the data type, and 0 is used to replace all illegal values

Let ints = new Int16array (["HI"]); Console.log (ints.length); 1console.log (Ints[0]); 0

This code attempts to add the string value "HI" to the Int16array array, the string is illegal in the training array, so the value is converted to a 0 insert array, and the length of the array is still 1,ints[0] contains a value of 0

All methods that modify the training array value are subject to the same restrictions, for example, if the function passed in to the map () method returns an illegal value, the end will replace

Let ints = new Int16array ([+]),    mapped = ints.map (v = "HI"); Console.log (mapped.length);//2console.log (MAPP Ed[0]); 0console.log (mapped[1]); 0console.log (mapped instanceof Int16array); Trueconsole.log (mapped instanceof Array); False

The string "HI" here is not a 16-bit integer, so the result array will replace it with a. Due to the nature of this error correction, illegal data will not appear in the array, even if it is mixed with illegal data will not throw an error

"Missing Method"

Although the training array contains many of the same methods as normal arrays, it is missing several. The following methods are not available in the training array

Concat () Pop () push () Shift () splice () Unshift ()

In addition to the concat () method, the methods in this list can change the size of the array, because the dimensions of the training array cannot be changed, so these methods do not apply to the training array. The train array does not support the concat () method because the combined result of two training arrays (especially when two arrays handle different data types) becomes indeterminate, which directly violates the original intention of using the training array.

"Additional Methods"

There are also two methods set () and Subarray () that do not appear in the normal array in the training array. The function of these two methods is reversed, the set () method copies the other array to the existing training array, and Subarray () extracts part of an existing training array as a new training array

The set () method accepts two parameters: one is an array (either a trained array or an ordinary array is supported), one is an optional offset that indicates where the data is to be inserted, and if nothing is passed, the default offset is 0. Valid data is copied from the array passed in as a parameter to the target training array

Let ints = new Int16array (4), Ints.set ([+]), Ints.set ([], 2); Console.log (ints.tostring ()); 25,50,75,100

This code creates an array of 4 elements Int16array, first calling the set () method to copy two values to the first two locations, calling the set () method again and passing in the offset 2, and copying the other two values to the last two positions of the array

The Subarray () method accepts two parameters: one is an optional start position, one is an optional end position (same as the end position of the slice () method, does not contain the data at the current position), and finally returns a new training array. You can also omit these two parameters to clone a new training array

Let ints = new Int16array ([[+], [[]],    subints1 = Ints.subarray (),    subints2 = Ints.subarray (2),    Subint S3 = Ints.subarray (1, 3); Console.log (subints1.tostring ()); 25,50,75,100console.log (Subints2.tostring ()); 75,100console.log (Subints3.tostring ()); 50,75

In the example above, 3 different training arrays were created from the original array ints. Array subints1 are obtained by cloning ints, so they contain the same information; the array subints2 copies the data starting at index 2, so it contains only the last two elements of the array ints (75 and 100); the array subints3 because of the call to Subarray () method, the SUBINTS3 contains only the two elements in the middle of the array ints, when the start and end indexes are passed in.

ES6 Stereotypes Array

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.