因为JavaScript具有自动垃圾回收机制,所以对于前端开发来说,内存空间并不是一个经常被提及的概念,很容易被大家忽视。特别是很多不是计算机专业的朋友在进入到前端之后,会对内存空间的认知比较模糊,甚至有些人干脆就是一无所知。
在很长一段时间里认为内存空间的概念在JS的学习中并不是那么重要。可当我回过头来重新整理JS基础时,发现由于对它的模糊认知,导致了许多知识理解得并不明白。比如最基本的引用数据类型和引用传递到底是怎么回事儿?浅复制与深复制有什么不同?闭包到底是什么?等等。
因此,想要对JS的理解更加深刻,就必须对内存空间有一个清晰的认知。
在学习内存空间之前,我们需要对三种数据结构有一个清晰的理解。他们分别是堆(heap),栈(stack)与队列(queue)。
- 栈(stack)
JS中不明确区分栈内存和堆内存的概念,可以简单理解成都是堆存储;
执行上下文中会运用到栈的思维,即函数调用栈
栈遵循先进后出原则,FILO
- 堆(heap)
堆数据结构是一种树状结构,以数组的形式存储。它的存取数据的方式,则与书架与书非常相似。
只要关心key
- 队列(queue)
主要运用在事件循环(Event Loop)中
队列遵循先进先出原则,FIFO
- 变量对象和基础类型
JS基础类型:Null Undefined String Number Boolean Symbol BigInt
基础类型保存在变量对象中
- 引用类型与堆内存
JS引用类型:Object Array Function Date RegExp
引用类型的值大小不固定,他们的值保存在堆内存中,JS不允许直接操作内存,
在操作对象时,实际上是在操作对象的引用而不是实际的对象,引用是保存该对象的一个地址,与内存关联
内存空间demo
var a = 20; // 变量对象
var b = a; // 变量对象
b = 30;
console.log(a); // 20
var m = { a: 10, b: 20 }; // 变量m存在变量对象中,{ a: 10, b: 20 }存在堆内存中
var n = m;
n.a = 15;
console.log(m.a); // 15
- JS 内存生命周期和垃圾回收机制
JS有垃圾自动回收机制,垃圾收集器会定时触发,通过标记清除算法来查找不再继续使用的对象。
对于局部变量很容易进行判断,但是全局变量很难判断,因此要尽量避免使用全局变量
1、分配所需要的内存
2、使用分配到的内存(读、写)
3、不需要时释放内存
var a = 20; // 在内存中给数值变量分配空间
alert(a + 100); // 使用内存
a = null; // 使用完毕之后,释放内存空间