JS 的学习往往最常用的是在电子商务 WordPress 网站建设中,JS 除了基本资料型别,阵列就是资料组合,当然肯定还会有在我们电子商务 WordPress 网站建设中我们没有学习或者很少学习到的阵列,下面我们就来讲讲电子商务 WordPress 网站建设学习中 JS 阵列问题。

 

  我写的很多东西都是因为要完成某些特定的功能而刻意总结的,可以算是备忘,本文也是如此。前段时间一直在研究 Web Audio API 以及语音通讯相关的知识,内容侧重于音讯流在 AudioContext 各个节点之间的流动情况,而现在要摸清楚音讯到流底是个什么样的资料格式,所以对 ArrayBuffer 的研究就显得格外重要了。

 

  一、 Array 在记忆体中的堆叠模型

 

  1. Array 的获取

 

  Javascript 中如何产生 Array:

 

  JavaScript

 

  [element0, element1, …, elementN]

 

  new Array(element0, element1, …, elementN)

 

  new Array(arrayLength)

 

  直接定义,或者通过建构函式建立一个 Array,当然也可以使用其他的手段:

 

  JavaScript

 

  ”array”.split(“”);

 

  ”array”.match(/a|r/g);

 

  等等,方式有很多。但是 Array 内部是个什么样的结构,恐怕很多人还不是很清楚。

 

  2. 堆叠模型

 

  在阵列中我们可以放很多不同资料型别的资料,如:

 

  JavaScript

 

  var arr = [21, “ 李靖”, new Date(), function(){}, , null];

 

  上面这个阵列中一次放入了 数字、字串、物件、函式、 undefined 和 null,对于上面的资料介面我们可以具象的描述下:

 

  JavaScript

 

  栈

 

  +———+ 堆

 

  | 21 | +——————-+

 

  +———+ | |

 

  | “ 李靖” | | |

 

  +———+ | +——–+ |

 

  | [refer] |———–>| Object | |

 

  +———+ | +——–+ |

 

  | [refer] |—————–>+——–+ |

 

  +———+ | |function| |

 

  |undefined| | +——–+ |

 

  +———+ | |

 

  | null | +——————-+

 

  +———+ Created By Barret Lee

 

  JavaScript 的资料型别分为两种,一种是值型别,一种是引用型别,常见的引用型别有 Object 和 Array,阵列的储存模型中,如果是诸如 Number 、 String 之类的值型别资料会被直接压入栈中,而引用型别只会压入对该值的一个索引,用 C 语言的概念来解释就是只储存了资料的指标,这些资料是储存在堆中的某块区间中。栈堆并不是独立的,栈也可以在堆中存放。

 

  好了,对 Array 的说明就到这里,下面具体说说 ArrayBuffer 的相关知识。

 

  二、 ArrayBuffer

 

  web 是个啥玩意儿,web 要讨论的最基本问题是什么? 我觉得有两点,一个是资料,一个是资料传输,至于资料的展示,纷繁复杂,这个应该是 web 上层的东西。而本文要讨论的 ArrayBuffer 就是最基础的资料型别,甚至不能称之为资料型别,它是一个资料容器,需要通过其他方式来读写。

 

  官方点的定义:

 

  The 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 an ArrayBufferView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.

 

  表示二进位制资料的原始缓冲区,该缓冲区用于储存各种型别化阵列的资料。 无法直接读取或写入 ArrayBuffer,但可根据需要将其传递到型别化阵列或 DataView 物件 来解释原始缓冲区。

 

  他是一个二进位制资料的原始缓冲区,虽然 JavaScript 是弱型别语言,但是他本身是对资料的型别和大小都有限制的,我们需要通过某种资料结构将缓冲区的内容有序的读取出来 (写进去) 。

 

  1. 原始缓冲区的建立

 

  通过 ArrayBuffer 这个建构函式可以建立一个原始缓冲区:

 

  JavaScript

 

  var buffer = new ArrayBuffer(30);

 

  从 chrome 控制台可以看到:

 

  

 

 

  buffer 例项拥有一个 byteLength 的属性,用于获取 buffer 的 size,一个只有 IE11+ 以及 ios6+ 支援的 slice 方法,用于对 buffer 长度进行撷取操作。

 

  JavaScript

 

  ArrayBuffer slice(

 

  unsigned long begin

 

  unsigned long end Optional

 

  );

 

  可以测试这个 DEMO:

 

  JavaScript

 

  var buffer = new ArrayBuffer(12);

 

  var x = new Int32Array(buffer);

 

  x[1] = 1234;

 

  var slice = buffer.slice(4);

 

  var y = new Int32Array(slice);

 

  console.log(x[1]);

 

  console.log(y[0]);

 

  x[1] = 6789;

 

  console.log(x[1]);

 

  console.log(y[0]);

 

  2. 型别化阵列

 

  型别化阵列型别表示可编制索引和操纵的 ArrayBuffer 物件 的各种检视。 所有阵列型别的长度均固定。

 

  Int 就是整型,Uint 为无符号整形,Float 为浮点型,这些是 C 语言中的基本概念,我就不具体解释了。由于这些检视化结构都是大同小异,本文只对 Float32Array 型别作说明,读者可以举一反三。

 

  Float32Array 跟 Array 是十分类似的,只不过他每一个元素都是都是一个 32 位 (4 字节) 的浮点型资料。 Float32Array 一旦建立其大小不能再修改。

 

  我们可以直接建立一个 Float32Array:

 

  JavaScript

 

  var x = new Float32Array(2);

 

  x[0] = 17;

 

  console.log(x[0]); // 17

 

  console.log(x[1]); // 0

 

  console.log(x.length); // 2

 

  需要有这么一个概念,他依然是一个阵列,只不过该阵列中的每个元素都是 Float 32 位的资料型别,再如:

 

  JavaScript

 

  var x = new Float32Array([17, -45.3]);

 

  console.log(x[0]); // 17

 

  console.log(x[1]); // -45.29999923706055

 

  console.log(x.length); // 2

 

  我们把一个阵列的值直接赋给了 x 这个 Float32Array 物件,那么在储存之前会将它转换成一个 32 位浮点数。

 

  由于该类阵列的每个元素都是同一型别,所以在堆叠模型中,他们全部会被压入到栈之中,因此型别化阵列都是值型别,他并不是引用型别! 这个要引起注意,从下面的例子中也可以反映出来:

 

  JavaScript

 

  var x = new Float32Array([17, -45.3]);

 

  var y = new Float32Array(x);

 

  console.log(x[0]); // 17

 

  console.log(x[1]); //-45.29999923706055

 

  console.log(x.length); // 2

 

  x[0] = -2;

 

  console.log(y[0]); // 17, y 的值没变

 

  将 x 的值复制给 y,修改 x[0], y[0] 并没有变化。

 

  除了上面的方式,我们还可以通过其他方式来建立一个型别化阵列:

 

  JavaScript

 

  var buffer = new ArrayBuffer(12);

 

  var x = new Float32Array(buffer, 0, 2);

 

  var y = new Float32Array(buffer, 4, 1);

 

  x[1] = 7;

 

  console.log(y[0]); // 7

 

  解释下这里为什么返回 7.

 

  JavaScript

 

  ArrayBuffer(12)

 

  +-+-+-+-+-+-+-+-+-+-+-+-+-+

 

  |0|1|2|3|4|5|6|7|8| | | | |

 

  +-+-+-+-+-+-+-+-+-+-+-+-+-+

 

   /

 

  x (Float32Array)

 

  offset:0

 

  byteLength:4

 

  length:2

 

  JavaScript

 

  ArrayBuffer(12)

 

  +-+-+-+-+-+-+-+-+-+-+-+-+-+

 

  |0|1|2|3|4|5|6|7|8| | | | |

 

  +-+-+-+-+-+-+-+-+-+-+-+-+-+

 

   /

 

  y

 

  Created By Barret Lee

 

  看了上面的图解还有疑问么? 我觉得我不用继续解释了。可以把 ArrayBuffer 的单位看成 1,而 Float32Array 的单位是 4.

 

  3. DataView 物件

 

  DataView 物件对资料的操作更加细致,不过我觉得没啥意思,上面提到的各种型别化阵列已经可以基本满足应用了,所以这里就一笔带过,一个简单的示例:

 

  JavaScript

 

  var buffer = new ArrayBuffer(12);

 

  var x = new DataView(buffer, 0);

 

  x.setInt8(0, 22);

 

  x.setFloat32(1, Math.PI);

 

  console.log(x.getInt8(0)); // 22

 

  console.log(x.getFloat32(1)); // 3.1415927410125732

 

  三、 XHR2 中的 ArrayBuffer

 

  ArrayBuffer 的应用特别广泛,无论是 WebSocket 、 WebAudio 还是 Ajax 等等,前端方面只要是处理大资料或者想提高资料处理效能,那一定是少不了 ArrayBuffer 。

 

  XHR2 并不是什么新东西,可能你用到了相关的特性,却不知这就是 XHR2 的内容。最主要的一个东西就是 xhr.responseType ,他的作用是设定响应的资料格式,可选引数有:”text” 、”arraybuffer” 、”blob” 或”document” 。请注意,设定 (或忽略) xhr.responseType = ” 会预设将响应设为”text” 。这里存在一个这样的对应关系:

 

  请求 响应

 

  text DOMString

 

  arraybuffer ArrayBuffer

 

  blob Blob

 

  document Document

 

  举个栗子:

 

  JavaScript

 

  var xhr = new XMLHttpRequest();

 

  xhr.open(‘GET’, ‘/path/to/image.png’, true);

 

  xhr.responseType = ‘arraybuffer’;

 

  xhr.onload = function(e) {

 

  // this.response == uInt8Array.buffer

 

  var uInt8Array = new Uint8Array(this.response);

 

  };

 

  xhr.send();

 

  我们在 xhr.responseType 中设定了属性为 arraybuffer,那么在拿到的资料中就可以用型别化阵列来接受啦。

 

  JS 不是那么容易学习的,尤其是自己通过学习来搭建电子商务 WordPress 网站更是非常困难,上述简单介绍了一下 JS 阵列。