栈 | 堆 | 队列


参考链接

栈(stack)

栈是一种高效的数据结构,遵循LIFO(last in first out)的的进出原则,也就是说,最后进入的元素会先出来。这样的操作很快,也很容易实现,在很多的编程语言中都有用到栈的概念。浏览器的前进后退功能就类似于栈的概念。

简单的理解就是类似于我们砌墙,先砌的砖块总是在最下面,而最后砌的砖在最上面,当我们需要依次拆墙的时候,便会先拆上面的砖块,这就是LIFO。(这里排除将墙推倒的抬杠理论)

var arr = [1, 2, 3, 4, 5];
arr.push(6); // 存入数据 arr -> [1, 2, 3, 4, 5, 6]
arr.pop();   // 取出数据 arr -> [1, 2, 3, 4, 5]

如上,在数组中的push和pop方法就可以看成是栈的进出概念。

堆(heap)

堆的特点是无序,遵循“key–>value”的原则,可以看做是object的模式。
好比我们去超市买东西,我们明确我们需要的东西,比如口香糖,那么口香糖就是作为key,我们拿着key去超市拿我们需要的产品就行了,不在乎他是先存储的还是后存储的。堆跟顺序没有关系,并且不限制出口,只要有key就能拿到我们需要的数据。

队列(queue)

队列是遵循FIFO(first in first out)的先进先出原则。类似于我们去排队买饭,先排的人就可以先买。

在数据中表现为,从后面存入,但是从前面取出。

var arr = [1, 2, 3, 4, 5];
arr.push(6); // 存入数据 arr -> [1, 2, 3, 4, 5, 6]
arr.shift();   // 取出数据 arr -> [1, 2, 3, 4, 5]

如上,在数组中通过push进行数据注入,但是shift从头取数据。

JS中的堆和栈

js的执行过程就是进栈和出栈的过程。

当脚本要调用一个函数时,JS解析器把该函数推入栈中(push)并执行
当函数运行结束后,JS解释器将它从堆栈中推出(pop)

内存存储

js的数据类型分为两种:
基础数据类型:String、Boolean、Null、Undefined、Symbol、Number
引用类型 :Object(array、function、object)

基础类型的值保存在栈中,这些值有固定的大小,按值来访问。
引用类型的值保存在堆中,栈中存储的是引用类型的类型和指针(也可以叫引用地址)。引用类型的值没有固定大小,可以进行扩展,就像一个对象,可以添加元素。

const str = '';
const obj = {name:''}

如上,string是一个字符串,属于基础类型,那么它就是直接存在栈中的。
而obj是一个对象,可以理解为obj是由obj字符串和{name:’’}两部分构成。obj只是一个字符串,存在栈中,{name:’’}是一个对象存在堆中,那么obj字符串的结果就是{name:’’}在堆中的地址。

浅copy与深copy

浅拷贝与深拷贝是js中老生常谈的话题。根据上面堆栈的描述,我们可以理解为拷贝只会拷贝栈中的元素。

基础数据类型的拷贝不分深拷贝与浅拷贝,但是引用数据类型我们通常的“=”赋值,只是拷贝了它在栈中的存储地址,会导致两个地址指向了同一个堆中的对象,也称为浅拷贝。

const obj = {};
const obj2 = JSON.parse(JSON.stringify(obj));

如上我们通过JSON自带的两个方法进行深拷贝。先将对象转成字符串,再解析成对象,也就是说现将对象转字符串存在栈中,再从栈中进行取出来解析,便会在堆中新开辟出来一个空间来存储一个对象。

注意:在函数中,对象的传递也是引用,在函数中实参是一个对象时,我们进行修改,便会影响函数外部对象的值

垃圾回收机制

js与所有的编程语言一样,内存管理不善也会引起内存泄漏。导致用户浏览器占用电脑内存过高,造成卡顿等问题。

js有自动垃圾回收机制,通过标记清除的算法来识别哪些变量不再使用,对其进行销毁。
开发者也可以通过手动设置变量值为null来标记清除,让其失去引用,以便于下次内存回收机制进行回收。

局部环境中,函数执行完成后,函数局部环境声明的变量不再需要时,就会被垃圾回收销毁(理想的情况下,闭包会阻止这一过程)。

全局环境只有页面退出时才会出栈,解除变量引用。所以开发者应尽量避免在全局环境中创建全局变量,如需使用,也要在不需要时手动标记清除,将其内存释放掉。

垃圾回收算法除了"标记清除",还有一种"引用计数"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值