变量对象与堆内存
var a = 20;
var b = 'abc';
var c = true;
var d = { m: 20 }
,因为javascript具有自动垃圾回收机制,所以对于前端开发来说,内存空间并不是一个经常被提及的概念,很容易被大家忽视。特别是很多不是计算机专业的朋友在进入前端之后,会对内存空间的认知比较模糊,甚至有些人就是一无所知。
当然也包括我自己。
在很长一段时间里认为内存空间的概念在JS的学习中并不是那么重要。可当我回过头来重新整理JS基础时,发现由于对它的模糊认知,导致了许多知识理解得并不明白。比如最基本的引用数据类型和引用传递到底是怎么回事?浅复制和深复制有什么不同?闭包到底是什么?等等。
因此,想要对JS的理解更加深刻,就必须对内存空间有一个清晰的认知。
在学习内存空间之前,我们需要对三种数据结构有一个清晰的理解。他们分别是堆(heap),栈(stack)与队列(queue).
一、栈数据结构
与C/C++不同,JavaScript中并没有严格意思上区分栈内存与堆内存。因此我们可以简单粗暴的理解为JavaScript的所有数据都保存在堆内存中。但是在某些场景,我们仍然需要基于栈数据结构的思维来实现一些功能,比如JavaScript的执行上下文(关于执行上下文我会在下一篇文章中总结)。执行上下文的执行顺序借用了栈数据的存取方式(也就是后面我们会经常提到的函数调用栈)。因此理解栈数据结构的原理与特点十分重要。
要简单理解栈的存取方式,我们可以通过类比乒乒球盒子来分析。如下图左侧。
乒乒球盒子与栈类比
这种乒乒球的存放方式与栈中存取数据的方式如出一辙。处于盒子中最顶层的乒乒球5,它一定是最后被放进去。但可以最先被使用。而我们想要使用底层的乒乒球1,就必须将上面的4个乒乒球取出来,让乒乒球1处于盒子顶层。这就是栈空间先进后出,后进先出的特点。图中已经详细的表明栈空间的存储原理。
二、堆数据结构
堆数据结构是一种树状结构。它的存取数据的方式,则与书架与书非常相似。
书虽然也整齐的存放在书架上,但是我们只要知道书的名字,就可以方便的取出来我们想要的书,而不用像从乒乒球盒子里去乒乒球,非得将上面的所有乒乒球拿出来才能取到中间的某一个乒乒球。好比在JSON格式的数据中,我们存储的key-value是可以无序,因为顺序的不同并不影响我们的使用,我们只需要关心书名字。