最近在纠结一个问题,就是数组这个引用类型在JavaScript 中是不是和其他语言一样开辟了一个连续的内存来存储,但是在JS 中每个元素又可以是不同的类型,这就导致了没办法用一个相同大小的存储,所以数组究竟是如何在JS 存储的呢? 难道它是一个“假数组”?

结论:

参考了一些网上的文章,直接上总结吧。

  1. JS中有快数组和慢数组之分:

    • 快数组:

      是一种线性的存储方式,内部存储是连续的内存;

      可能需要开辟一大块供其使用,其中还可能有很多空洞,是比较费内存的;

      空间连续的,遍历速度很快;
    • 慢数组:

      慢数组是一种字典的内存形式,在内存中是零散分配的;

      遍历效率较差;

      【注】:不用开辟大块连续的存储空间,节省了内存,但是由于需要维护这样一个HashTable,其效率会比快数组低,V8中是以Dictionary的结构实现的慢数组;
    • 快慢数组的转换:(具体参考下面的链接)

      从源码中我们可以得出结论:

      • 如果快数组扩容后的容量是原来的 3 倍以上,意味着它比 HashTable 形式存储占用更大的内存,快数组会转换为慢数组;
      • 如果快数组新增的索引与原来最大索引的差值大于 1024,快数组会被转换会慢数组。(之前的例子:[(arr.length + 1026) - (arr.length - 1)] = 1027 > 1024,故 arr 由快数组转为慢数组。)
  2. 类型化数组(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;

参考链接:

JavaScript 之 数组在内存中的存储方式(连续或不连续)的更多相关文章

  1. QList介绍(QList比QVector更快,这是由它们在内存中的存储方式决定的。QStringList是在QList的基础上针对字符串提供额外的函数。at()操作比操作符[]更快,因为它不需要深度复制)非常实用

    FROM:http://apps.hi.baidu.com/share/detail/33517814 今天做项目时,需要用到QList来存储一组点.为此,我对QList类的说明进行了如下翻译. QL ...

  2. <转载>浅谈C/C++的浮点数在内存中的存储方式

    C/C++浮点数在内存中的存储方式 任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100.则在Intel CPU架构的系统中 ...

  3. C语言中浮点数在内存中的存储方式

    关于多字节数据类型在内存中的存储问题 //////////////////////////////////////////////////////////////// int ,short 各自是4. ...

  4. Float在内存中的存储方式及IEC61131处理

    Float在内存中的存储方式及IEC61131处理 1,fp32(32bits float)类型数据在存储器中占用4Bytes存储,且遵循IEEE-754标准: 一个浮点数分三部分组成: 符号位s(1 ...

  5. 数据在内存中的存储方式( Big Endian和Little Endian的区别 )(x86系列则采用little endian方式存储数据)

    https://www.cnblogs.com/renyuan/archive/2013/05/26/3099766.html 1.故事的起源 “endian”这个词出自<格列佛游记>.小 ...

  6. C# 数组在内存中的存储

    C# 数组是引用类型,那么在内存中是如何存储的呢? 在VS中调试C#程序,如何查看内存.寄存器.反汇编 在这篇文章里看到了如何在VS 中查看内存 先断点打在数组创建后语句那里,点debug->W ...

  7. JavaScript 之 数据在内存中的存储和引用

    栈和堆 大家都知道,JS中的数据类型包括两种:简单数据类型(String.Number.Boolean.undefined.null)和复杂数据类型(object). 在内存中分为栈区(stack)和 ...

  8. C/C++浮点数在内存中的存储方式

    一.内存表示 任何数据在内存中都是以二进制的形式存储的,浮点数的表示是把一个数的有效数字和数的范围在计算机的一个存储单元中分别予以表示,数的小数点位置随比例因子的不同而在一定范围内自由浮动.如下图是3 ...

  9. float和double在内存中的存储方式

    本文转载于:http://wenku.baidu.com/link?url=ARfMiXVHCwCZJcqfA1gfeVkMOj9RkLlR9fIexbgs9gDdV8rIS48A1_xe1y6YgX ...

  10. C/C++数据在内存中的存储方式

    目录 1 内存地址 2 内存空间   在学习C/C++编程语言时,免不了和内存打交道,在计算机中,我们存储有电影,文档,音乐等数据,这些数据在内存中是以什么形式存储的呢?下面做一下简单介绍. 本文是学 ...

随机推荐

  1. Cendos中启动docker失败的问题

    注:在 Windows中使用Linux虚拟机中使用Cendos 刚开始安装Docker时没有任何错误, 但是在后续的docker启动过程中, 出现以下问题: 按提示使用 systemctl statu ...

  2. 【当年笔记】Collection集合部分

    集合继承关系图 1)Vector 特点:线程安全,消耗偏大 2)ArrayList 特点:基于数组实现,随机访问某个元素效率高.集和头尾之间包括头插入删除操作效率较低,因为插入元素后,其他元素要后移. ...

  3. springboot gradle 加速问题

    初始化项目使用阿里云 seriver url : https://start.spring.io 直接修改为: https://start.aliyun.com 关键的gradle 修改安装包地址 g ...

  4. redis相关入门知识

    redis介绍:是一种基于键值对的NoSql数据库,与许多键值对数据库不同是,它可以由string,hash,list,set,zest(有序集合).Bitmaps(位图).HyperLogLog.G ...

  5. 在uniapp中,定义导航栏左侧,右侧按钮

    在page.json中 代码: { "path": "pages/pandian", "style": { "navigation ...

  6. eKuiper 1.8.0 发布:零代码实现图像/视频流的实时 AI 推理

    LF Edge eKuiper 是 Golang 实现的轻量级物联网边缘分析.流式处理开源软件,可以运行在各类资源受限的边缘设备上.eKuiper 的主要目标是在边缘端提供一个流媒体软件框架(类似于 ...

  7. 阿里云IPSec的一些问题

    1.阿里云IPSec无法进行多段连接单个IPSec连接 解决方案  在阿里云端需要如下操作 1.单个VPN网关下创建多个IPSec连接  连接属性一致  使用兴趣流模式.打开nat转换.  2段对2段 ...

  8. GuiLite 学习笔记(一) Mainloop与ViewTree

    以GuiLiteSamples中的HelloSlide 为例,剖析一下GuiLite的设计思路和刷新机制: 首先是main.cpp; 可以分成3部分: 1.根据fb mode拿到对应的phy_fb, ...

  9. python multiprocessing多进程 cannot pickle '_io.TextIOWrapper' object

    Python 3.9.6 在windows下使用multiprocessing多进程报如下错误,但linux下正常 Traceback (most recent call last): File &q ...

  10. linux重置密码和单用户模式

    CentOS7.9 CentOS7系统root密码丢失找回方法(史上最好) 1. 重新启动或开启CentOS7系统,在选择进入系统Grub菜单界面如下图1-1,根据提示按"e"小写 ...