最近在纠结一个问题,就是数组这个引用类型在JavaScript 中是不是和其他语言一样开辟了一个连续的内存来存储,但是在JS 中每个元素又可以是不同的类型,这就导致了没办法用一个相同大小的存储,所以数组究竟是如何在JS 存储的呢? 难道它是一个“假数组”?
结论:
参考了一些网上的文章,直接上总结吧。
-
JS中有快数组和慢数组之分:
- 快数组:
是一种线性的存储方式,内部存储是连续的内存;
可能需要开辟一大块供其使用,其中还可能有很多空洞,是比较费内存的;
空间连续的,遍历速度很快; - 慢数组:
慢数组是一种字典的内存形式,在内存中是零散分配的;
遍历效率较差;
【注】:不用开辟大块连续的存储空间,节省了内存,但是由于需要维护这样一个HashTable,其效率会比快数组低,V8中是以Dictionary的结构实现的慢数组; - 快慢数组的转换:(具体参考下面的链接)
从源码中我们可以得出结论:- 如果快数组扩容后的容量是原来的 3 倍以上,意味着它比 HashTable 形式存储占用更大的内存,快数组会转换为慢数组;
- 如果快数组新增的索引与原来最大索引的差值大于 1024,快数组会被转换会慢数组。(之前的例子:[(arr.length + 1026) – (arr.length – 1)] = 1027 > 1024,故 arr 由快数组转为慢数组。)
- 快数组:
-
类型化数组(Typed Arrays)
JavaScript 类型化数组是一种类似数组的对象,并提供了一种用于访问原始二进制数据的机制。
由缓冲和视图两部分: 缓冲是由ArrayBuffer实现,视图时由DataView来实现:- ArrayBuffer 是一种数据类型,用来表示一个通用的、固定长度的二进制数据缓冲区;(不能直接操作ArrayBuffer内容)
- DataView是创建的一个类型化数组的视图或一个用来描述缓冲数据格式,可以使用它们读写缓冲区中的内容;
[总]:一块大的连续的内存区域,可以用它来做一些高效的存取操作等。
var buffer = new ArrayBuffer(4); var arr = new Int32Array(buffer); for(var i=0; i<LIMIT; i++) arr[i]=i;
参考链接:
原创文章,作者:端木书台,如若转载,请注明出处:https://blog.ytso.com/267838.html