你需要知道的JavaScript内存空间知识

我穿越了,文章写于2019-11-24。

前言

" 相信接触过Java、Python等后端语言的同学来说,内存空间是一个老生常谈的话题,但是作为前端开发的同学来说,这个并不会被经常提及,并且在日常编码中并不会注意一些细节问题。比如面试中常会问到的深拷贝与浅拷贝、按值传递和按引用传递等,如果从内存空间的角度去理解,会发现对你JS又有了更深的理解。 "

01 内存生命周期

在JS中,一般可以将内存分为两种:栈(包含池)、堆。其声明周期可以大概分为三个阶段:

  • 内存分配(声明)
  • 内存读写(使用)
  • 内存回收(销毁)

02 栈内存与基础数据类型

JS基础数据类型:Number、String、Boolean、Null、undefined、symbol、bigInt(自行了解)。

以上这些值都有固定大小,一般都保存在栈内存中,由系统分配固定的内存空间大小。我们在操作的时候直接操作内存中的值,即也就是在传递中是按值传递,遵循后进先出的原则进行读取。

需要强调的是,JS在执行过程中执行流进入一个函数时,会生成一个当前函数的执行环境(EC),并且推入到栈内存中,即我们所说的环境栈。所以JS在执行过程中消耗的是栈内存。

03 堆内存与引用数据类型

JS引用数据类型:Object、Array、Date、RegExp等。

引用数据类型的值时保存在堆内存中的对象,其内存空间大小是动态分配的。需要注意的是,JavaScript中不能直接访问堆内存中的位置,即不能直接操作对内存对象。而我们在平时操作引用数据类型的时候,其实操作的是这个对象的内存地址。相对应的,这个地址会被保存在栈内存中,形成一个映射关系。

举个例子:

js 复制代码
var a = { b: 1 }; 
var c = 100; 
function fn(a1, c1) { 
    a1.b = 1000; 
    a1 = null; 
    c1 = 200; 
} 
fn(a, c); 
console.log(a); 
console.log(c);

这是一道简单的题目,但是很好的表达了上面的堆栈原理。

答案是:{b: 1000}和100

当传递a的时候,实际上传递的是当前a对象的引用(地址)给了a1,其存储在栈内存中,执行a1.b = 1000进行修改的时,会通过这个地址去操作堆内存的对象,将b的值改为1000;接着a1 赋值为null,那么这时候a1就不会再指向堆内存,但是a的引用还是存在,所以对象变为修改后的{b: 1000},这就是所谓的按引用传递

而当传递实参c给形参c1的过程中,会把100直接复制新的一份给了c1,此时修改c1200后,实际上操作的就是c1这个变量,而不会影响原来的c,即该过程是按值传递。

04 内存回收

JavaScript中,自带有垃圾回收机制。其工作原理是会在每个固定时间执行一次内存释放操作,它内部有一套具体的回收机制,通过这个机制去找那些不再使用的值,回收对应内存。

标记清除法

这个是目前JavaScript最常用的垃圾收集方式。

请看下面代码

js 复制代码
var a = 100;
console.log(a + 10086);
a = null;

可以理解为当JS执行流进入这个环境的时候,会首先将a标记为"进入环境",当a离开环境时(a = null),则将其标记为"离开环境"。在垃圾收集器运行时,回收标记为"离开环境"的变量,释放内存。

引用计数法

这个是早期Netscape浏览器下一种不太常见的垃圾收集策略,由于这种方式不能回收循环引用的变量,导致对应内存不能被及时回收。后面放弃了这种方式,转而采用了标记清除来实现。

引用计数算法定义"内存不再使用"的标准很简单,就是看一个变量的引用次数是否为0。如果为0,说明该变量已经不再需要了。

综合以上,我们在日常开发中需要注意当变量不需要再使用的时候,请将其内存及时归还(赋值为null),特别是全局变量、定时器、DOM节点、闭包等等。

相关推荐
BillKu4 分钟前
npm 安装命令中关于 @ 的讲解,如:npm install @vue-office/docx vue-demi
前端·vue.js·npm
bestadc8 分钟前
LeetCode 几道 Promises 和 Time 的题目
javascript·算法·leetcode
yangzhi_emo17 分钟前
ES6笔记4
前端·笔记·es6
萌萌哒草头将军23 分钟前
Node.js v24.8.0 新功能预览!🚀🚀🚀
前端·javascript·node.js
超人不会飛26 分钟前
大模型应用 Vue H5 模板:快速落地流式交互与富文本渲染的开箱方案
前端·vue.js·github
用户4582031531727 分钟前
CSS无需JavaScript的交互效果实现
前端·css
影i29 分钟前
在 Vue + Codemirror 中优雅回显 JSON
前端
奇怪的前端729 分钟前
Alien-Signals 响应式系统
前端·vue.js
你单排吧34 分钟前
Electron打包图标修改失败问题
前端
@AfeiyuO37 分钟前
vue3 实现将页面生成 pdf 导出(html2Canvas + jspdf)
前端·pdf·vue