二进制数组

概述

  二进制数组(ArrayBuffer对象、TypedArray视图和DataView视图)是JS操作二进制数据的一个接口。这些对象早就存在,属于独立的规格(2011年2月发布),ES6将它们纳入了ECMAScript规格,并且增加了新的方法。
  二进制数组的原始设计目的,与WebGL项目有关。所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JS与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个32位整数,两端的JS脚本与显卡都要进行格式转化,将非常耗时。这时要是存在一种机制,可以像C语言那样,直接操作字节,将4个字节的32位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。
  二进制数组就是在这种背景下诞生的。它很像C语言的数组,允许开发者以数组下标的形式,直接操作内存,大大增强了JS处理二进制数据的能力,使得开发者有可能通过JS与操作系统的原生接口进行二进制通信。
  二进制数组由三类对象组成
  1、ArrayBuffer对象:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。
  2、TypedArray(类型化数组):共包括9种类型的类型化数组,比如Uint8Array(无符号8位整数)数组,Int16Array(16位整数)数组,Float32Array(32位浮点数)数组等等。
  3、DataView(数据视图):可以自定义复合格式的视图,比如第一个字节是Uint8(无符号8位整数)、第二、三个字节是Int16(16位整数)、第四个字节开始是Float32(32位浮点数)等等,此外还可以自定义字节序。
  简单说,ArrayBuffer对象代表原始的二进制数据,TypedArray(类型化数组)用来读写简单类型的二进制数据,DataView(数据视图)用来读写复杂类型的二进制数据。
  [注意]二进制数组并不是真正的数组,而是类数组对象
  很多浏览器操作的API,用到了二进制数组操作二进制数据,比如:File API、XMLHttpRequest、Fetch API、Canvas、WebSockets。

ArrayBuffer

  ArrayBuffer对象代表储存二进制数据的一段内存,它不能直接读写,只能通过TypedArray(类型化数组)和DataView(数据视图)以指定格式解读二进制数据。
  [注意]IE9-浏览器不支持
  ArrayBuffer是一个构造函数,可以分配一段可以存放数据的连续内存区域。参数length表示要创建的数组缓冲区的大小,即所需要的内存大小(以字节为单位)。最终返回一个新的拥有指定大小的ArrayBuffer对象。它的内容都被初始化为0。
  下面代码生成了一段32字节的内存区域,为了读写这段内容,需要为它指定视图。比如DataView数据视图,它的创建,需要提供ArrayBuffer对象实例作为参数。代码对一段32字节的内存,建立DataView视图,然后以不带符号的8位整数格式,读取第一个元素,结果得到0,因为原始内存的ArrayBuffer对象,默认所有位都是0。

var buf = new ArrayBuffer(32);
var dataView = new DataView(buf);
dataView.getUint8(0) // 0

  另一种TypedArray视图(类型化数组),与DataView数据视图的一个区别是,它不是一个构造函数,而是一组构造函数,代表不同的数据格式。

var buffer = new ArrayBuffer(12);
var x1 = new Int32Array(buffer);
x1[0] = 1;
var x2 = new Uint8Array(buffer);
x2[0] = 2;
x1[0] // 2

  上面代码对同一段内存,分别建立两种视图:32位带符号整数(Int32Array构造函数)和8位不带符号整数(Uint8Array构造函数)。由于两个视图对应的是同一段内存,一个视图修改底层内存,会影响到另一个视图。
  TypedArray视图(类型化数组)的构造函数,除了接受ArrayBuffer实例作为参数,还可以接受普通数组作为参数,直接分配内存生成底层的ArrayBuffer实例,并同时完成对这段内存的赋值。

var typedArray = new Uint8Array([0,1,2]);
typedArray.length // 3
typedArray[0] = 5;
typedArray // [5, 1, 2]

  上面代码使用TypedArray视图的Uint8Array构造函数,新建一个不带符号的8位整数视图。可以看到,Uint8Array直接使用普通数组作为参数,对底层内存的赋值同时完成。
  目前,TypedArray视图(类型化数组)一共包括9种类型,每一种视图都是一种构造函数。

数据类型   字节长度   含义                             对应的C语言类型

Int8       1        8位带符号整数                      signed char
Uint8      1        8位不带符号整数                    unsigned char
Uint8C     1        8位不带符号整数(自动过滤溢出)        unsigned char
Int16      2        16位带符号整数                     short
Uint16     2        16位不带符号整数                   unsigned short
Int32      4        32位带符号整数                     int
Uint32     4        32位不带符号的整数                  unsigned int
Float32    4        32位浮点数                         float
Float64    8        64位浮点数                         double

  这9个构造函数生成的数组,统称为TypedArray视图(类型化数组)。它们很像普通数组,都有length属性,都能用方括号运算符([])获取单个元素,所有数组的方法,在它们上面都能使用。普通数组与TypedArray数组的差异主要在以下方面:
  1、TypedArray数组的所有成员,都是同一种类型
  2、TypedArray数组的成员是连续的,不会有空位
  3、TypedArray数组成员的默认值为0。比如,new Array(10)返回一个普通数组,里面没有任何成员,只是10个空位;new Uint8Array(10)返回一个TypedArray数组,里面10个成员都是0
  4、TypedArray数组只是一层视图,本身不储存数据,它的数据都储存在底层的ArrayBuffer对象之中,要获取底层对象必须使用buffer属性

数据视图

  如果一段数据包括多种类型(比如服务器传来的HTTP数据),这时除了建立ArrayBuffer对象的复合视图以外,还可以通过DataView视图进行操作。
  DataView视图提供更多操作选项,而且支持设定字节序。本来,在设计目的上,ArrayBuffer对象的各种TypedArray视图,是用来向网卡、声卡之类的本机设备传送数据,所以使用本机的字节序就可以了;而DataView视图的设计目的,是用来处理网络设备传来的数据,所以大端字节序或小端字节序是可以自行设定的。
  DataView视图本身也是构造函数,接受一个ArrayBuffer对象作为参数,生成视图。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 这个部分如果没有C语言和计算机基础会比较难理解,如果实在理解不了可以收藏它,日后再看。 二进制数组其实很早就有了,...
    faremax阅读 1,584评论 0 0
  • 二进制数组(ArrayBuffer对象、TypedArray视图和DataView视图)是JavaScript操作...
    呼呼哥阅读 21,262评论 2 12
  • ES6中包含一系列的对二进制数组的包装类,用于快捷的创建、存储、操作二进制数组。这些二进制数组被广泛的应用到文件操...
    淡蓝色梦想阅读 830评论 0 0
  • 爱过一个人 爱空了 心也空了 再也找不到一个人 会给我如此的安全感 再也找不到一个人 会让我如此愉悦 以为,会一直...
    沁妖阅读 241评论 0 0
  • 墨子是中国历史上唯一一个农民出身的哲学家,墨子创立了墨家学说,墨家在先秦时期影响很大,与儒家并称“显学”。他提出了...
    孙君001阅读 510评论 0 0