Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 775189 of JavaScript typed arrays

  • Revision slug: Web/JavaScript/Typed_arrays
  • Revision title: JavaScript typed arrays
  • Revision id: 775189
  • Created:
  • Creator: fscholz
  • Is current revision? No
  • Comment minor tweaks to the last edit
Tags: 

Revision Content

{{JSRef("Global_Objects", "TypedArray", "ArrayBuffer,DataView,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array")}}

JavaScript typed arrays are array-like objects and provide a mechanism for accessing raw binary data. As you already know, {{jsxref("Array")}} objects grow and shrink dynamically and can have any JavaScript value. JavaScript engines perform optimizations so that these arrays are fast. However, as web applications become more and more powerful, adding features such as audio and video manipulation, access to raw data using WebSockets, and so forth, it has become clear that there are times when it would be helpful for JavaScript code to be able to quickly and easily manipulate raw binary data in typed arrays.

Buffers and views: typed array architecture

To achieve maximum flexibility and efficiency, JavaScript typed arrays split the implementation into buffers and views. A buffer (implemented by the {{jsxref("ArrayBuffer")}} object) is an object representing a chunk of data; it has no format to speak of, and offers no mechanism for accessing its contents. In order to access the memory contained in a buffer, you need to use a view. A view provides a context — that is, a data type, starting offset, and number of elements — that turns the data into an actual typed array.

Typed arrays in an ArrayBuffer

ArrayBuffer

The {{jsxref("ArrayBuffer")}} is a data type that is used to represent a generic, fixed-length binary data buffer. You can't directly manipulate the contents of an ArrayBuffer; instead, you create a typed array view or a {{jsxref("DataView")}} which represents the buffer in a specific format, and use that to read and write the contents of the buffer.

Typed array views

Typed array views have self descriptive names and provide views for all the usual numeric types like Int8, Uint32, Float64 and so forth. There is one special typed array view, the Uint8ClampedArray. It clamps the values between 0 and 255. This is useful for Canvas data processing, for example.

{{page("/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", "TypedArray_objects")}}

DataView

The {{jsxref("DataView")}} is a low-level interface that provides a getter/setter API to read and write arbitrary data to the buffer. This is useful when dealing with different types of data, for example. Typed array views are in the native byte-order (see {{Glossary("Endianness")}}) of your platform. With a DataView you are able to control the byte-order. It is big-endian by default and can be set to little-endian in the getter/setter methods.

Web APIs using typed arrays

FileReader.prototype.readAsArrayBuffer()
The FileReader.prototype.readAsArrayBuffer() method starts reading the contents of the specified Blob or File.
XMLHttpRequest.prototype.send()
XMLHttpRequest instances' send() method now supports typed arrays and {{jsxref("ArrayBuffer")}} objects as argument.
ImageData.data
Is a {{jsxref("Uint8ClampedArray")}} representing a one-dimensional array containing the data in the RGBA order, with integer values between 0 and 255 inclusive.

Examples

Using views with buffers

First of all, we will need to create a buffer, here with a fixed length of 16-bytes:

var buffer = new ArrayBuffer(16);

At this point, we have a chunk of memory whose bytes are all pre-initialized to 0. There's not a lot we can do with it, though. We can confirm that it is indeed 16 bytes long, and that's about it:

if (buffer.byteLength === 16) {
  console.log("Yes, it's 16 bytes.");
} else {
  console.log("Oh no, it's the wrong size!");
} 

Before we can really work with this buffer, we need to create a view. Let's create a view that treats the data in the buffer as an array of 32-bit signed integers:

var int32View = new Int32Array(buffer);

Now we can access the fields in the array just like a normal array:

for (var i = 0; i < int32View.length; i++) {
  int32View[i] = i * 2;
}

This fills out the 4 entries in the array (4 entries at 4 bytes each makes 16 total bytes) with the values 0, 2, 4, and 6.

Multiple views on the same data

Things start to get really interesting when you consider that you can create multiple views onto the same data. For example, given the code above, we can continue like this:

var int16View = new Int16Array(buffer);

for (var i = 0; i < int16View.length; i++) {
  console.log("Entry " + i + ": " + int16View[i]);
}

Here we create a 16-bit integer view that shares the same buffer as the existing 32-bit view and we output all the values in the buffer as 16-bit integers. Now we get the output 0, 0, 2, 0, 4, 0, 6, 0.

You can go a step farther, though. Consider this:

int16View[0] = 32;
console.log("Entry 0 in the 32-bit array is now " + int32View[0]);

The output from this is "Entry 0 in the 32-bit array is now 32". In other words, the two arrays are indeed simply views on the same data buffer, treating it as different formats. You can do this with any view types.

Working with complex data structures

By combining a single buffer with multiple views of different types, starting at different offsets into the buffer, you can interact with data objects containing multiple data types. This lets you, for example, interact with complex data structures from WebGL, data files, or C structures you need to use while using js-ctypes.

Consider this C structure:

struct someStruct {
  unsigned long id;
  char username[16];
  float amountDue;
};

You can access a buffer containing data in this format like this:

var buffer = new ArrayBuffer(24);

// ... read the data into the buffer ...

var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);

Then you can access, for example, the amount due with amountDueView[0].

Note: The data structure alignment in a C structure is platform-dependent. Take precautions and considerations for these padding differences.

Conversion to normal arrays

After processing a typed array, it is sometimes useful to convert it back to a normal array in order to benefit from the {{jsxref("Array")}} prototype. This can done using {{jsxref("Array.from")}}, or using the following code where Array.from is unsupported.

var typedArray = new Uint8Array([1, 2, 3, 4]),
    normalArray = Array.prototype.slice.call(typedArray);
normalArray.length === 4;
normalArray.constructor === Array;

Specifications

Specification Status Comment
Typed Array Specification Obsolete Superseded by ECMAScript 6.
{{SpecName('ES6', '#sec-typedarray-objects', 'TypedArray Objects')}} {{Spec2('ES6')}} Initial definition in an ECMA standard.

Browser compatibility

Chrome 7 includes support for ArrayBuffer, Float32Array, Int16Array, and Uint8Array. Chrome 9 and Firefox 15 add support for DataView objects. Internet Explorer 10 supports all types except Uint8ClampedArray and ArrayBuffer.prototype.slice which are present starting in Internet Explorer 11.

{{CompatibilityTable}}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 7.0 {{ CompatGeckoDesktop("2") }} 10 11.6 5.1
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 4.0 {{CompatVersionUnknown}} {{ CompatGeckoMobile("2") }} 10 11.6 4.2

See also

Revision Source

<div>{{JSRef("Global_Objects", "TypedArray", "ArrayBuffer,DataView,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array")}}</div>

<p>JavaScript typed arrays are array-like objects and provide a mechanism for accessing raw binary data. As you already know, {{jsxref("Array")}} objects grow and shrink dynamically and can have any JavaScript value. JavaScript engines perform optimizations so that these arrays are fast. However, as web applications become more and more powerful, adding features such as audio and video manipulation, access to raw data using WebSockets, and so forth, it has become clear that there are times when it would be helpful for JavaScript code to be able to quickly and easily manipulate raw binary data in typed arrays.</p>

<h2 id="Buffers_and_views.3A_typed_array_architecture">Buffers and views: typed array architecture</h2>

<p>To achieve maximum flexibility and efficiency, JavaScript typed arrays split the implementation into <strong>buffers</strong> and <strong>views</strong>. A buffer (implemented by the {{jsxref("ArrayBuffer")}} object) is an object representing a chunk of data; it has no format to speak of, and offers no mechanism for accessing its contents. In order to access the memory contained in a buffer, you need to use a view. A view provides a context — that is, a data type, starting offset, and number of elements — that turns the data into an actual typed array.</p>

<p><img alt="Typed arrays in an ArrayBuffer" src="https://mdn.mozillademos.org/files/8629/typed_arrays.png" style="width: 666px; height: 278px;" /></p>

<h3 id="ArrayBuffer">ArrayBuffer</h3>

<p>The {{jsxref("ArrayBuffer")}} is a data type that is used to represent a generic, fixed-length binary data buffer. You can't directly manipulate the contents of an <code>ArrayBuffer</code>; instead, you create a typed array view or a {{jsxref("DataView")}} which represents the buffer in a specific format, and use that to read and write the contents of the buffer.</p>

<h3 id="Typed_array_views">Typed array views</h3>

<p>Typed array views have self descriptive names and provide views for all the usual numeric types like <code>Int8</code>, <code>Uint32</code>, <code>Float64</code> and so forth. There is one special typed array view, the <code>Uint8ClampedArray</code>. It clamps the values between 0 and 255. This is useful for <a href="/en-US/docs/Web/API/ImageData">Canvas data processing</a>, for example.</p>

<p>{{page("/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", "TypedArray_objects")}}</p>

<h3 id="DataView">DataView</h3>

<p>The {{jsxref("DataView")}} is a low-level interface that provides a getter/setter API to read and write arbitrary data to the buffer. This is useful when dealing with different types of data, for example. Typed array views are in the native byte-order (see {{Glossary("Endianness")}}) of your platform. With a <code>DataView</code> you are able to control the byte-order. It is big-endian by default and can be set to little-endian in the getter/setter methods.</p>

<h2 id="Web_APIs_using_typed_arrays">Web APIs using typed arrays</h2>

<dl>
 <dt><a href="/en-US/docs/Web/API/FileReader#readAsArrayBuffer()" title="/en-US/docs/Web/API/FileReader#readAsArrayBuffer()"><code>FileReader.prototype.readAsArrayBuffer()</code></a></dt>
 <dd>The <code>FileReader.prototype.readAsArrayBuffer()</code> method starts reading the contents of the specified <a href="/en-US/docs/Web/API/Blob" title="/en-US/docs/DOM/Blob"><code>Blob</code></a> or <a href="/en-US/docs/Web/API/File" title="/en-US/docs/DOM/File"><code>File</code></a>.</dd>
 <dt><a href="/en-US/docs/Web/API/XMLHttpRequest#send()" title="/en-US/docs/Web/API/XMLHttpRequest#send()"><code>XMLHttpRequest.prototype.send()</code></a></dt>
 <dd><code>XMLHttpRequest</code> instances' <code>send()</code> method now supports typed arrays and {{jsxref("ArrayBuffer")}} objects as argument.</dd>
 <dt><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/ImageData">ImageData.data</a></code></dt>
 <dd>Is a {{jsxref("Uint8ClampedArray")}} representing a one-dimensional array containing the data in the RGBA order, with integer values between <code>0</code> and <code>255</code>&nbsp;inclusive.</dd>
</dl>

<h2 id="Examples">Examples</h2>

<h3 id="Using_views_with_buffers">Using views with buffers</h3>

<p>First of all, we will need to create a buffer, here with a fixed length of 16-bytes:</p>

<pre class="brush:js">
var buffer = new ArrayBuffer(16);
</pre>

<p>At this point, we have a chunk of memory whose bytes are all pre-initialized to 0. There's not a lot we can do with it, though. We can confirm that it is indeed 16 bytes long, and that's about it:</p>

<pre class="brush:js">
if (buffer.byteLength === 16) {
  console.log("Yes, it's 16 bytes.");
} else {
  console.log("Oh no, it's the wrong size!");
} 
</pre>

<p>Before we can really work with this buffer, we need to create a view. Let's create a view that treats the data in the buffer as an array of 32-bit signed integers:</p>

<pre class="brush:js">
var int32View = new Int32Array(buffer);
</pre>

<p>Now we can access the fields in the array just like a normal array:</p>

<pre class="brush:js">
for (var i = 0; i &lt; int32View.length; i++) {
  int32View[i] = i * 2;
}
</pre>

<p>This fills out the 4 entries in the array (4 entries at 4 bytes each makes 16 total bytes) with the values 0, 2, 4, and 6.</p>

<h3 id="Multiple_views_on_the_same_data">Multiple views on the same data</h3>

<p>Things start to get really interesting when you consider that you can create multiple views onto the same data. For example, given the code above, we can continue like this:</p>

<pre class="brush:js">
var int16View = new Int16Array(buffer);

for (var i = 0; i &lt; int16View.length; i++) {
  console.log("Entry " + i + ": " + int16View[i]);
}
</pre>

<p>Here we create a 16-bit integer view that shares the same buffer as the existing 32-bit view and we output all the values in the buffer as 16-bit integers. Now we get the output 0, 0, 2, 0, 4, 0, 6, 0.</p>

<p>You can go a step farther, though. Consider this:</p>

<pre class="brush:js">
int16View[0] = 32;
console.log("Entry 0 in the 32-bit array is now " + int32View[0]);
</pre>

<p>The output from this is "Entry 0 in the 32-bit array is now 32". In other words, the two arrays are indeed simply views on the same data buffer, treating it as different formats. You can do this with any <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#TypedArray_objects" title="JavaScript typed arrays/ArrayBufferView#Typed array subclasses">view types</a>.</p>

<h3 id="Working_with_complex_data_structures">Working with complex data structures</h3>

<p>By combining a single buffer with multiple views of different types, starting at different offsets into the buffer, you can interact with data objects containing multiple data types. This lets you, for example, interact with complex data structures from <a href="/en-US/docs/Web/WebGL" title="WebGL">WebGL</a>, data files, or C structures you need to use while using <a href="/en-US/docs/Mozilla/js-ctypes" title="js-ctypes">js-ctypes</a>.</p>

<p>Consider this C structure:</p>

<pre class="brush:cpp">
struct someStruct {
  unsigned long id;
  char username[16];
  float amountDue;
};</pre>

<p>You can access a buffer containing data in this format like this:</p>

<pre class="brush:js">
var buffer = new ArrayBuffer(24);

// ... read the data into the buffer ...

var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);</pre>

<p>Then you can access, for example, the amount due with <code>amountDueView[0]</code>.</p>

<div class="note"><strong>Note:</strong> The <a href="https://en.wikipedia.org/wiki/Data_structure_alignment" title="https://en.wikipedia.org/wiki/Data_structure_alignment">data structure alignment</a> in a C structure is platform-dependent. Take precautions and considerations for these padding differences.</div>

<h3 id="Conversion_to_normal_arrays">Conversion to normal arrays</h3>

<p>After processing a typed array, it is sometimes useful to convert it back to a normal array in order to benefit from the {{jsxref("Array")}} prototype. This can done using {{jsxref("Array.from")}}, or using the following code where <code>Array.from</code> is unsupported.</p>

<pre class="brush:js">
var typedArray = new Uint8Array([1, 2, 3, 4]),
    normalArray = Array.prototype.slice.call(typedArray);
normalArray.length === 4;
normalArray.constructor === Array;
</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td><a href="https://www.khronos.org/registry/typedarray/specs/latest">Typed Array Specification</a></td>
   <td>Obsolete</td>
   <td>Superseded by ECMAScript 6.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-typedarray-objects', 'TypedArray Objects')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>Initial definition in an ECMA standard.</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>Chrome 7 includes support for <code>ArrayBuffer</code>, <code>Float32Array</code>, <code>Int16Array</code>, and <code>Uint8Array</code>. Chrome 9 and Firefox 15 add support for <code>DataView</code> objects. Internet Explorer 10 supports all types except <code>Uint8ClampedArray</code> and <code>ArrayBuffer.prototype.slice</code> which are present starting in Internet Explorer 11.</p>

<p>{{CompatibilityTable}}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>7.0</td>
   <td>{{ CompatGeckoDesktop("2") }}</td>
   <td>10</td>
   <td>11.6</td>
   <td>5.1</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>4.0</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{ CompatGeckoMobile("2") }}</td>
   <td>10</td>
   <td>11.6</td>
   <td>4.2</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer" title="/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer">Getting <code>ArrayBuffer</code>s or typed arrays from <em>Base64</em>-encoded strings</a></li>
 <li><a href="/en-US/docs/Code_snippets/StringView" title="/en-US/docs/Web/JavaScript/Typed_arrays/StringView"><code>StringView</code> – a C-like representation of strings based on typed arrays</a></li>
 <li><a href="https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays">Faster Canvas Pixel Manipulation with Typed Arrays</a></li>
 <li><a href="https://www.html5rocks.com/en/tutorials/webgl/typed_arrays">Typed Arrays: Binary Data in the Browser</a></li>
 <li>{{Glossary("Endianness")}}</li>
</ul>
Revert to this revision