es6二进制数组--基础
一、概念
二进制数组由 ArrayBuffer对象 TypeArray 视图和DataView视图 三部分组成是javascript操作二进制数据的一个接口。
早在2011年2月就已经发布,但是由于ES6 的出现,将这些对象添加了一些新的方法。它是一种类似C语言中直接操作字节的机制。 产生背景
这个接口的原始设计目的,与WebGL项目有关。所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的、
实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个32位整数,两端的JavaScript脚本与显卡都要进行格式转化,将非常耗时。
这时要是存在一种机制,可以像C语言那样,直接操作字节,将4个字节的32位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。 它很像C语言的数组,允许开发者以数组下标的形式,直接操作内存,大大增强了JavaScript处理二进制数据的能力,使得开发者有可能通过JavaScript与操作系统的原生接口进行二进制通信。 二、ArrayBuffer对象:代表原始的二进制数据。可以通过TypeArray 进行操作,即可以操作内存
它不能直接读写,只能通过(TypedArray
和DataView
)来读写。
ArrayBuffer
也是一个构造函数,可以分配一段可以存放数据的连续内存区域。
例如我想生成一段32字节的内存区域,每个字节的值默认都是0,就可以这样创建:
var buffer32 = new ArrayBuffer(32);
var buffer = new ArrayBuffer();
console.log(buf);
如上图所示:
ArrayBuffer 的实力上 有一个 byteLength的属性,原型上有一个slice方法,还有共有方法 isView 下面我们来给大家一一解读
byteLength
:是ArrayBuffer
实例的属性,返回所分配的内存区域的字节长度。
buffer32.byteLength == 32 true
需要注意的是:如果你想分配一块比较大的内存区域,需要检查是否分配成功,因为可能没有那么多的连续空余内存。
if(buffer.byteLength === n){
//成功
}else{
//失败
}
slice
:有两个参数,第一个参数表示开始拷贝的字节序号(包含此字节),第二个参数表示截止拷贝的字节序号(不含此字节),如果省略第二个参数,则默认截止到原ArrayBuffer
对象的结尾。
slice
:是ArrayBuffer
实例的一个方法,允许将内存区域的一部分,拷贝生成一个新的ArrayBuffer
对象。
var buffer = new ArrayBuffer(8);
var newBuffer = buffer.slice(0, 3);
console.log(buffer); // { byteLength: 8 }
console.log(newBuffer);//{ byteLength: 3 }
ArrayBuffer.isView()
isView
:是ArrayBuffer
的一个静态方法,返回一个布尔值,表示参数是否为ArrayBuffer
的视图实例。这个方法大致相当于判断参数,是否为TypedArray
实例或DataView
实例。
var buffer = new ArrayBuffer(8);
ArrayBuffer.isView(buffer) // false
var v = new Int32Array(buffer);
ArrayBuffer.isView(v) // true
三. TypedArray 视图
TypedArray数组只提供9种固定的构造函数,用来生成相应类型的数组实例。
(1)TypedArray(buffer, byteOffset=0, length?)
视图的构造函数可以接受三个参数:
第一个参数(必需):视图对应的底层
ArrayBuffer
对象。第二个参数(可选):视图开始的字节序号,默认从0开始。
第三个参数(可选):视图包含的数据个数,默认直到本段内存区域结束。
// 创建一个8字节的ArrayBuffer
var b = new ArrayBuffer(8); // 创建一个指向b的Int32视图,开始于字节0,直到缓冲区的末尾
var v1 = new Int32Array(b); // [0, 0] 不是很理解 // 创建一个指向b的Uint8视图,开始于字节2,直到缓冲区的末尾
var v2 = new Uint8Array(b, 2);//[0, 0, 0, 0, 0, 0] // 创建一个指向b的Int16视图,开始于字节2,长度为2
var v3 = new Int16Array(b, 2, 2);//[0, 0]
v1[0]是一个32位整数,指向字节0~字节3;v2[0]是一个8位无符号整数,指向字节2;v3[0]是一个16位整数,指向字节2~字节3。只要任何一个视图对内存有所修改,就会在另外两个视图上反应出来。
注:byteOffset必须与所要建立的数据类型一致,比如:带符号的16位整数需要两个字节,所以byteOffset参数必须能够被2整除
(2)TypedArray(length)
视图还可以不通过ArrayBuffer
对象,直接分配内存而生成。
var f64a = new Float64Array(8); //64字节
f64a[0] = 10;
f64a[1] = 20;
f64a[2] = f64a[0] + f64a[1]; // 30
(3)TypedArray(typedArray)
TypedArray
数组的构造函数,可以接受另一个TypedArray
实例作为参数。
var typedArray = new Int8Array(new Uint8Array(4));
注:新数组会开辟一段新的内存存数据。
var x = new Int8Array([1, 1]);
var y = new Int8Array(x);
x[0] // 1
y[0] // 1
x[0] = 2;
y[0] // 1
//基于同一段内存
var x = new Int8Array([1, 1]);
var y = new Int8Array(x.buffer);
x[0] // 1
y[0] // 1
x[0] = 2;
y[0] // 2
(4)TypedArray(arrayLikeObject)
//普通数组生成TypedArray实例
var typedArray = new Uint8Array([1, 2, 3, 4]);
//这时TypedArray视图会重新开辟内存,不会在原数组的内存上建立视图
//TypedArray数组转换回普通数组
var normalArray = Array.prototype.slice.call(typedArray);
需要注意的是:TypedArray数组除了没有concat方法之外,拥有普通数组所有的操作方法和属性
如果想要合并多个TypedArray数组,可以用下面这个函数。
function concatenate(resultConstructor, ...arrays) {
let totalLength = 0;
for (let arr of arrays) {
totalLength += arr.length;
}
let result = new resultConstructor(totalLength);
let offset = 0;
for (let arr of arrays) {
result.set(arr, offset);
offset += arr.length;
}
return result;
}
concatenate(Uint8Array, Uint8Array.of(1, 2), Uint8Array.of(3, 4))
// Uint8Array [1, 2, 3, 4]
TypedArray数组也可以被遍历。
let ui8 = Uint8Array.of(0, 1, 2);
for (let byte of ui8) {
console.log(byte);
}
// 0
// 1
// 2
ArrayBuffer 与字符串的互相转换
注:字符串的编码方法是确定的,才可以相互转换。
// ArrayBuffer转为字符串,参数为ArrayBuffer对象
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
// 字符串转为ArrayBuffer对象,参数为字符串
function str2ab(str) {
var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
var bufView = new Uint16Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
TypedArray.prototype.buffer
:返回整段内存区域对应的ArrayBuffer对象,属性为只读。
TypedArray.prototype.byteLength
:返回TypedArray数组占据的内存长度,单位为字节,属性为只读。
TypedArray.prototype.byteOffset
:返回TypedArray数组从底层ArrayBuffer对象的哪个字节开始,属性为只读。
TypedArray.prototype.length
:TypedArray数组含有多少个成员。
TypedArray.prototype.set()
:用于复制数组(普通数组或TypedArray数组)。
TypedArray.prototype.subarray()
:对于TypedArray数组的一部分,再建立一个新的视图。
TypedArray.prototype.slice()
:返回一个指定位置的新的TypedArray实例。
TypedArray.of()
:用于将参数转为一个TypedArray实例。
TypedArray.from()
:返回一个基于这个结构的TypedArray实例。
3. 复合视图
var buffer = new ArrayBuffer(24);
var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);
上面代码将一个24字节长度的ArrayBuffer对象,分成三个部分:
字节0到字节3:1个32位无符号整数
字节4到字节19:16个8位整数
字节20到字节23:1个32位浮点数
4. DataView视图
DataView
实例有以下属性,含义与TypedArray
实例的同名方法相同。
DataView.prototype.buffer:返回对应的ArrayBuffer对象
DataView.prototype.byteLength:返回占据的内存字节长度
DataView.prototype.byteOffset:返回当前视图从对应的ArrayBuffer对象的哪个字节开始
DataView
实例提供8个方法读取内存。
getInt8:读取1个字节,返回一个8位整数。
getUint8:读取1个字节,返回一个无符号的8位整数。
getInt16:读取2个字节,返回一个16位整数。
getUint16:读取2个字节,返回一个无符号的16位整数。
getInt32:读取4个字节,返回一个32位整数。
getUint32:读取4个字节,返回一个无符号的32位整数。
getFloat32:读取4个字节,返回一个32位浮点数。
getFloat64:读取8个字节,返回一个64位浮点数。
DataView
视图提供8个方法写入内存。
setInt8:写入1个字节的8位整数。
setUint8:写入1个字节的8位无符号整数。
setInt16:写入2个字节的16位整数。
setUint16:写入2个字节的16位无符号整数。
setInt32:写入4个字节的32位整数。
setUint32:写入4个字节的32位无符号整数。
setFloat32:写入4个字节的32位浮点数。
setFloat64:写入8个字节的64位浮点数。
es6二进制数组--基础的更多相关文章
- ES6 二进制数组
二进制数组(ArrayBuffer对象.TypedArray视图和DataView视图)是JavaScript操作二进制数据的一个接口.这些对象早就存在,属于独立的规格(2011年2月发布),ES6将 ...
- 【C#基础】byte二进制数组转string
//解析post请求数组返回的数组 //解码返回的二进制数组 public string DecodeBytes(byte[] c) { string html = string.Empty; try ...
- ES6定型数组
前面的话 定型数组是一种用于处理数值类型(正如其名,不是所有类型)数据的专用数组,最早是在WebGL中使用的,WebGL是OpenGL ES 2.0的移植版,在Web 页面中通过 <canvas ...
- Java 数组基础
数组 数组(Array):相同类型数据的集合. 定义数组 方式1(推荐,更能表明数组类型) type[] 变量名 = new type[数组中元素的个数]; 比如: int[] a = new int ...
- Java 数组基础,java.util.Arrays
定义数组 方式1(推荐,更能表明数组类型) 方式2(同C语言) 方式3定义时直接初始化 数组运用基础 数组长度 equals() 数组元素不为基本数据类型时 二维数组 二维数组基础 变长的二维数组 j ...
- C#中将图片文件转化为二进制数组-用于数据库存储
在项目开发中,使用SQL Server存储数据,数据类型image可以保存图片.但是在存储之前需要将图片转化为二进制数组的形式进行赋值. 将图片文件转换为二进制数组 /// <summary&g ...
- java 图片Base64字符串转图片二进制数组
public static byte[] base64ToImgByteArray(String base64) throws IOException{ sun.misc.BASE64Decoder ...
- 分别使用ES5和ES6进行数组去重以及注意事项
ES6,ES5数组去重 使用Es6进行数组去重 var arr = [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN]; ...
- PHP 数组基础知识
php 数组基础知识function abc($a,$b,$c = 0){ echo $a,$b,$c;}abc(1,3); //调用方法 ////可变参数function def(){ $arr = ...
随机推荐
- jQuery---学习roadmap---4 parts
jQuery---学习roadmap---4 parts jQuery初识 jQuery让js的开发变得更加简单 jQuery解决了浏览器的兼容性问题 学习目标 使用jQuery设计常见的效果 掌握j ...
- 关于vue :style 的几种使用方式
:style的使用 一 ,最通用的写法 <p :style="{fontFamily:arr.conFontFamily,color:arr.conFontColor,backgrou ...
- OpenCV: “vector”: 未声明的标识符和Vector不是模板
漏写using namespace std: 会出现此错误“vector”: 未声明的标识符或者是将“vector”写成‘Vector’会出现Vector不是模板的错误:改正即可
- Controller-->View传值的几种方法
Controller --- > View 传值的方法 ViewBag ViewData TempData 向普通View页面传一个Model对象 向强类型页面传传一个Model对象 用一个Vi ...
- AcWing 275. 传纸条
#include<iostream> using namespace std ; ; *N][N][N]; int w[N][N]; int n,m; int main() { cin&g ...
- ubuntu中安装和卸载apache2
1. 安装apache2 安装命令: sudo apt-get install apache2 启动/停止/重启apache2: service apache2 start/stop/restart ...
- MyBatis-单表的增删改查(CRUD)操作
在学习MyBatis的单表的增删改查操作之前,还是再次熟悉下MyBatis这个框架,只有对其熟悉的情况下,才能很好的使用,灵活的开发. MyBatis优点: ...
- 生产环境实践:Cana实现MySQL到ES实时同步
注:由于文章篇幅有限,完整文档可扫下面二维码免费获取,更有深受好评的大数据实战精英+架构师好课等着你. 速点链接加入高手战队:http://www.dajiangtai.com/course/112. ...
- C++-POJ1018-Communication System
贪心算法:先排序,再枚举最小带宽(B),每次更新当前最小花费(P)和以及答案(ans) #include <cstdio> #include <algorithm> using ...
- selenium自动化之加载浏览器配置文件
化环境:python3.6 + selenium3 当我们做自动化的时候,如果不做任何配置的话打开的浏览器默认是不加载我们的浏览器配置文件的,下面我们来说说如何加载配置文件: 首先不管使用的是火狐浏览 ...