摘要:从执行上下文的生命周期来说,包括三个部分创建阶段执行阶段执行完毕阶段。三执行完毕阶段主要内容执行完毕后跳出执行上下文栈,等待被回收。这就完成了整个的执行上下文周期。
关于javascript中的从堆栈内存到执行上下文
先从计算机角度说一下内存:内存,包括三个部分:只读存储器(ROM)、随机存储器(RAM)和高速缓冲存储器(Cache)。
而其中,高速缓冲存储器(Cache)又分为三种:一级缓存(L1 Cache)、二级缓存(L2 Cache)、三级缓存(L3 Cache)。
当CPU需要数据的时候,就会先找缓存,因为缓存最快,缓存找不到,才去找慢一点的内存,然后找到后继续将数据放入缓存,下次还要的时候,还是先找缓存。
简单来说,缓存中的数据只是内存的一部分,但是读写速度最快,所以CPU先找它。
扯远了,回过头来。
再解释一下常说的“堆内存”、“栈内存”,“栈内存”也叫做“堆栈内存”,不是两个一起的总称,实际上就是栈内存,所以我这里就分别说“堆内存”和“栈内存”。
这里面就有“堆”和“栈”两个概念了。
先说说栈,它是放在是在于一级缓存中的,数据被调用的时候放入存储空间中,然后被调用完成时候,就会被立刻释放。
再说堆,它是放在二级缓存中的,它的生命周期由虚拟机的垃圾回收算法来决定。所以调用这些对象的速度要相对来得低一些。
举个很简单的例子来解释“堆”和“栈”这两个概念:
栈,有点像汉诺塔那样的套圈圈,一圈一圈地放上去,前面放的都被压在了底部,后面的就压在上面,一层一层叠罗汉,但是取出来的时候,就是后面放上去的先取出来,越早放进去的越后取出来,简单来说,就是迟来先上岸。
堆,就像是一堆东西那些,就好像你杂乱的房间,一堆杂物,你想找东西,翻来翻去,找到了,可以拿走,有些东西,你不拿走,放在那里,其实就是垃圾。
一般来说,javascript中的数据类型分为基本数据类型和引用数据类型,而基本数据类型中的变量名和变量直接存放在栈内存中,而引用数据类型的变量值实际上是存放的一个地址指针,所以它的变量名和变量值也是存放在栈内存中,而地址指向的实际内容,则是存放在堆内存中。
好了,开始说一下执行上下文了。
有些人会混淆执行上下文和作用域的概念,后面的文章我会说到作用域和作用域链,现在先说执行上下文。
从执行上下文的生命周期来说,包括三个部分:
1、创建阶段;2、执行阶段;3、执行完毕阶段。
一、创建阶段
执行上下文是在函数被调用的时候才创建,主要有三个内容:
1、创建变量对象;2、初始化作用域链;3、确定this的指向。
二、执行阶段
发生在函数代码执行阶段,主要有三个内容:
1、变量赋值;2、函数引用;3、执行其他代码。
三、执行完毕阶段
主要内容:执行完毕后跳出执行上下文栈,等待被回收。
关于创建阶段和执行阶段的具体内容,可能大家会有疑惑,里面的具体内容后面文章会慢慢细说。这里单纯说说执行上下文栈。
举个简单例子,函数里面也会有嵌套函数的情况,就像这样:
//函数father function father(age){ var me = age + 20; //函数son function son(age){ return age; } return son(me); } father(33);
既然执行上下文是函数被调用的时候创建的,那么上面这个father函数被调用之后,然后son也被调用了,那它们的执行上下文是什么关系呢?
在这里,Javascript会利用执行上下文栈(Execution context stack,ECS)来管理执行上下文。
回想一下前面栈内存的概念就很容易理解。
当调用某个函数的时候,就会创建执行上下文,并压入执行上下文栈中,当执行完毕的时候,就会从执行上下文栈中跳出,等待被回收。像上面这种函数内嵌套函数的情形,调用father函数的时候,father创建的执行上下文压入栈中,然后开始执行father的函数体内代码,因为father函数还没执行完毕,所以调用son函数时候会将son创建的执行上下文压入栈中,当son执行完毕,就会跳出,然后father执行完毕,继续跳出。这就完成了整个father的执行上下文周期。
还是那句,迟来先上岸的感觉。就好像下面的图这样(图片引用自网络),下面就是一个执行上下文栈,最底层肯定是全局了,然后只要函数没执行完毕继续在函数内调用其它函数的话,其它函数的执行上下文就会接着压上去,最后执行完毕,压在最上面的上下文先清出,然后其它执行上下文又变成最上面的了,然后执行完毕,继续清出,就和图那样了。
实际情况可能不是图的那样简单,可能清出到EC2那一层的时候,还没执行完这个函数,又调用其它函数,其它的执行上下文又接着压上去了。
当然,道理都是一样的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/84272.html
摘要:作用域的类别可以影响到变量的取值,分为词法作用域静态作用域和动态作用域。而,采用的就是词法作用域,或者叫静态作用域。 关于javascript中的作用域和作用域链 我GitHub上的菜鸟仓库地址: 点击跳转查看其他相关文章 文章在我的博客上的地址: 点击跳转 前面的文章说到, 执行上下文的创建阶段,主要有三个内容: 1、创建变量对象;2、初始化作用域...
摘要:每次调用函数时,都会创建一个新的执行上下文。理解执行上下文和堆栈可以让您了解代码为什么要计算您最初没有预料到的不同值的原因。 首发:https://www.love85g.com/?p=1723 在这篇文章中,我将深入研究JavaScript最基本的部分之一,即执行上下文。在这篇文章的最后,您应该更清楚地了解解释器要做什么,为什么在声明一些函数/变量之前可以使用它们,以及它们的值是如何...
摘要:如果在全局代码中调用函数,程序的顺序流进入被调用的函数,创建新的执行上下文并将其推送到执行堆栈的顶部。每次调用函数时,都会创建一个新的执行上下文。 翻译:疯狂的技术宅链接:http://davidshariff.com/blog/... 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 在这篇文章中,我将深入探讨JavaScript的最...
摘要:下面所有的东西都不为堆高我的编程能力,所以我只是把对的认识用最粗鄙的语言进行讲解和记录,所以,阅读需谨慎执行在执行之前会先进行编译。所以对纯前端尤其值得一提,不仅要知道怎么进行数据类型的转换更要清楚的知道你当下在操作的是什么数据类型。 下面所有的东西都不为堆高我的编程能力,所以我只是把对JS的认识用最粗鄙的语言进行讲解和记录,所以,阅读需谨慎! JS执行 JS在执行之前会先进行编译...
摘要:进阶期理解中的执行上下文和执行栈进阶期深入之执行上下文栈和变量对象但是今天补充一个知识点某些情况下,调用堆栈中函数调用的数量超出了调用堆栈的实际大小,浏览器会抛出一个错误终止运行。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第一期,本周的主题是调用堆栈,今天是第3天。 本计划一共28期,每期重点攻...
阅读 519·2021-08-31 09:45
阅读 1619·2021-08-11 11:19
阅读 867·2019-08-30 15:55
阅读 801·2019-08-30 10:52
阅读 2832·2019-08-29 13:11
阅读 2906·2019-08-23 17:08
阅读 2815·2019-08-23 15:11
阅读 3043·2019-08-23 14:33