我们知道在C语言中,可以使用mallocfree方法来分配和释放内存。随着web的发展中,js在ES6中新增了内存操作的支持。其实现方式就是---typed array。

typed array是个集体的概念。int8Array,Uint8Array,int16Array,Uint16Array等统统等称为typed array。通过这些类,开发者可以方便地读写内存中的二进制数据。

typed array在内部设计时分成了两部分:bufferviewbuffer层表示内存中的数据块,view负责提供操作数据块的接口。

ArrayBuffer

buffer层的底层实现就是基于ArrayBuffer类。ArrayBuffer的功能与malloc类似,为用户分配一块内存。

创建一个ArrayBuffer实例很简单,它接收一个参数,参数表示要分配多大的一块内存区域,字节为单位。下面的代码片段,分配了一块8字节的内存区:

var buffer = new ArrayBuffer(8);

我们还可以通过byteLength访问该实例的内存大小:

console.log(buffer.byteLength) // 8

使用slice方法创建一个新的实例,其内容复制原ArrayBuffer实例中的部分内容。

var buf2 = buffer.slice(0,2);

创建一个新的实例,分配2字节大小的内存,其内容复制buffer中索引为0和1的内存中的数据。

但是ArrayBuffer并不提供对内存读写的方法。如果要对该内存块进行操作,需要用到另一个类DataView

DataView

DataView类提供了访问ArrayBuffer的接口。其语法如下:

new DataView(buffer [, byteOffset [, byteLength]])

首先接收一个必传的buffer对象,该对象就是DataView实例接下来将要操作的内存块。其次是一个可选的byteOffset,该参数表示DataView实例要操作的buffer对象的开始位置。最后的参数指定要操作的buffer对象中元素的个数。
下面的代码片段演示了DataView如何操作ArrayBuffer

var buffer = new ArrayBuffer(16);
var dv = new DataView(buffer, 0);dv.setInt16(1, 42);
dv.getInt16(1); //42

示例中创建了一个DataView实例,该实例将buffer作为被操作的内存块,并且指定该内存块的16个字节都位于可操作区。
接着调用setInt16方法向从buffer的第2个字节开始存储带符号的16位整数。调用getInt16方法读出位于第2个字节处的带符号的16位整数。

typed array

如上所述,typed array的实现是组合了ArrayBufferDataView。也就是说typed array 通过ArrayBuffer创建内存块,通过DataView实现对内存块的读写操作。

typed array提供了多个类实现对同一块内存中的二进制数据按照不同的位数格式进行读写。如使用int8Array从内存中以带符号的8位整数的形式读写数据。

下面看一个例子来加深对typed array的理解

var buffer = new ArrayBuffer(16) //创建16b的内存区
var int32View = new Int32Array(buffer);
var int16View = new Int16Array(buffer);for (var i = 0; i < int32View.length; i++) {int32View[i] = i * 2;console.log(int32View[i]); // 0, 2, 4, 6
}for (var i = 0; i < int16View.length; i++) {console.log(int16View[i]); // 0, 0, 2, 0, 4, 0, 6, 0
}

buffer是一个ArrayBuffer实例,表示一块16b的内存区。同时创建了两个typed array,分别是32位和16位的。区别在于使用32位的访问buffer时,会把buffer(16b)以32位为单位划分为4个元素,读写都是以32位为单位进行的。16位的进行访问时,会把buffer(16b)以16位为单位划分为8个元素,每次读写都是16位。

第一个循环中,我们使用int32Viewbuffer中的4个元素中分别写入了0,2,4,6 4个整数。
很显然console中的结果是0,2,4,6

第二个循环中,我们使用int16View以16位的格式读取同一块内存,可以想象原来的4个元素变成了8个元素,因此读出的时候也会将原来的32位元素拆分为2个16位元素。因此console中的结果是0,0,2,0,4,0,6,0

有同学可能对输出的顺序不理解,觉得为什么不是0,0,0,2,0,4,0,6呢。这里稍微解释一下。
原因是默认情况下typed array 读取数据的时候都是以小端模式来返回的。

所谓的小端模式(Little-endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

上例在小端模式下的存储形式,每个框框表示16位。小端模式下数据的位权和地址的顺序是一致的,从小到大排列。

总结

typed array提供了一组读取不同字长的类数组对象如,int8Array,int16Array,int64Array来实现对内存的操作。typed array的底层实现是基于ArrayBufferDataView实现的,对内存的分配和内存的读取做了很好的分层设计。使用typed array使js向C语言等具备了操作二进制数据的能力。

理解 typed array相关推荐

  1. node.js下安装 webpack 的时候,出现:TypeError:this is not a typed array;

    在windows下安装webpack(前端打包工具,node环境已安装)的时候,控制台突然报了这个错误: C:\Users\admin\AppData\Roaming\npm\node_modules ...

  2. 使用vue脚手架的项目使用https: true,报错:Invalid typed array length: -4095

    使用vue脚手架的项目使用https: true,报错:Invalid typed array length: -4095 使用vue脚手架的项目使用https: true,报错:Invalid ty ...

  3. JS Typed Array 定型数组

    定型数组(typed array)是一种类似数组的对象,提供了一种用于在内存缓冲区中访问原始二进制数据的机制,可以提升向原生库传输数据的效率. 历史由来 随着浏览器的流行,人们期待通过它来运行复杂的 ...

  4. Typed Array常量资源

    部分转自http://blog.csdn.net/i_lovefish/article/details/9634399 Typed Array资源有点类似于Symbian中瘦模板类的,用于存放多种不同 ...

  5. Mybatis foreach 使用与理解(支持Array,List,HashMap及相互嵌套)

    2019独角兽企业重金招聘Python工程师标准>>> Mybatis foreach 使用与理解(支持List<Hashmap<String,String>> ...

  6. 理解Array.prototype.reduce()的执行过程

    之前对reduce()一直不理解,今天专门看了一遍MDN文档感觉明白了一些.在此记录一下自己的一些理解. Array.prototype.reduce()方法的作用: 对数组中的每个元素执行一次传入的 ...

  7. 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型

    FormData 对象的使用地址:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/Using_FormData_Objects 一. ...

  8. 前端基础知识:理解 Web Worker

    保持应用程序的流畅(smooth)和灵敏(responsive)是具有好的性能的应用程序的目标.按照 RAIL 模型,灵敏意味着响应用户行为的时间控制在 100ms 内,而流畅意味着屏幕上任何元素移动 ...

  9. foreach判断最后一个_JavaScript很简单?那你理解的forEach真的对吗?

    你理解的Array.prototype.forEach真的对吗? Array.prototype.forEach 我们都知道,forEach() 方法对数组的每个元素执行一次给定的函数.它的语法也很简 ...

最新文章

  1. 【django轻量级框架】使用支付宝支付接口(沙箱)
  2. ASP.Net TextBox控件只允许输入数字
  3. eclipse 提交git失败_简单10步教你使用eclipse整合gitee码云实现共享开发
  4. 期末考试前的预习,科目:化工设备与反应器(4)
  5. myBatis抛出异常Result Maps collection already contains value ...
  6. Flink安装及使用
  7. 原来C语言还可以这样实现“泛型编程”!
  8. java实现记事本查找_Java实现记事本
  9. 朱兴杰(1986-),男,泰康保险集团股份有限公司数据信息中心应用创新高级工程师...
  10. android outofmemory 原理及解决方案
  11. Arcgis Javascript那些事儿(四)--feature access服务编辑feature本质
  12. PHP去掉Bom标记
  13. Excel 连接 MySQL 导入数据 自定义 SQL (Excel 2016 + 适用)
  14. 使用VC2005一些问题及解决方案
  15. Python数据处理Tips数据样本不均衡解决方法
  16. JAVA阻止继承:final类和方法
  17. Ubuntu分区扩容
  18. QT实现简单的医院管理系统
  19. 08 Git中本地工作与远程仓库的同步
  20. linux gulp 安装教程,linux – 安装gulp browserify始终给出错误

热门文章

  1. 2.曲柄摇机构优化问题
  2. 穷困潦倒的作者凭借手机游戏“你猜我画”一夜暴富
  3. 获取其它小程序的appid和path
  4. 金融风控-- >申请评分卡模型-- >申请评分卡介绍
  5. unityplayer.dll丢失怎么办?有什么好的修复方法?
  6. 【报告分享】2021大中学生职业规划调查-新浪图数室头条(附下载)
  7. 国内优秀低代码平台有哪些?推荐这20家
  8. AI系列边缘计算盒子
  9. 牛客网华为云服务器,【华为云】-搭建私有云盘心得体会
  10. Win10 系统不使用软件设置状态栏透明效果