javascript每句代码背后的故事三

原创 天下无双 随笔 原生javascript 92阅读 2019-02-21 19:43:52 举报

我们每天都在写函数,调用函数,但在这个过程中发生了什么,可能很多人不知道,今天我就来说下这个过程中发生了什么。

在函数执行前,会先生成执行上下文,什么是函数执行上下文,说白了就是在函数执行前的一些准备工作,里面包含了这个函数执行时的必要条件比如变量对象,作用域等。这个执行上下文会有三种,全局执行上下文,函数执行上下文,eval函数执行上下文,这些上下文都要放在一个环境里所以对应就有全局环境,函数环境,eval函数环境。

javascript运行时候首先会进入全局环境生成全局上下文,然后我们写的所有函数进行调用就会进入对应函数环境生成对应函数的上下文。

因为javascript是单线程的,一个时间段只能执行一个任务。所以执行这些函数就需要按照顺序,执行函数按照顺利来,那执行上下文就要按照顺序放,javascript管理这些执行上下文存放的方式就是用栈的方式也就是所谓的执行栈。

栈的存储方式就是先进后出,所以正在执行的函数的执行上下文肯定是在上面的,执行完后弹出栈。举个例子

上面这个函数在执行的时候首先入栈的肯定是test1的执行上下文,最后进栈的肯定是test2执行上下文,但是不要忘记前面说的有个全局执行上下文,虽然我们看不见它,但是真正第一个进栈的是这个全局执行上下文,所以这个全局执行上下文永远在栈底,最后一个出栈,那test2就是第一个执行完出栈的函数。

函数入栈执行,执行完后出栈,这是一个非常有序的过程,但是有一种情况打断这种过程导致函数的执行上下文一直在栈里,这就是我们所谓的闭包,如果我们通过执行栈的方式来理解闭包就简单了,把上面函数改一下,让它产生闭包

我们按照上面的思路来看,全局执行上下文进栈,test1的执行上下文进栈,test1执行完成,这时候test1应该出栈了,但是因为test3需要执行用到了test1的执行上下文其实就是里面的变量a,所以test1不能出栈,它出栈的话这个执行上下文就会被销毁也就是变量a就会被销毁,这时候test3入栈了,然后执行完出栈。所以栈里就只剩下test1的执行上下文和全局上下文,只有在网页关闭或者手动把引用解除test3 = null,才会让test1出栈被垃圾回收收走。

栈的大小是有上限的如果我们一直产生闭包,一直不清除,那会让这个栈里堆积的执行上下文越来越多,最后就会导致页面卡顿。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复