执行上下文
执行上下文是一个抽象的概念,代表了代码执行的环境,包含:执行环境,变量对象,this,作用域链。
.流程:
——js引擎在js代码正式执行之前会创建一个执行环境
——进入该环境以后创建一个变量对象,改对象用于收集:变量、函数、函数的参数、this。(找关键字var function)
——确认this的指向
——创建作用域链
——分函数和全局()
——每调用一次函数创建一次执行上下文。
作用域链
作用域链是真实存在的,是一个数组结构,该结构中保存着一个个变量对象。
他们之间的关系
首先我们要缕清:
js代码在执行之前会创建一个执行环境。
在进入这个环境后会创建一个变量对象。
那作用域链是什么呢,其实就是函数的一个属性
上面这个图是我用浏览器这个审查元素看的,也就是F12.
然后我们把断点设置到14行,这一行其实没有任何意义,只是为了让这整个js代码有所执行,方便我们用工具去观察。
看上面的代码我们可以看到,其实我们定义的两个函数fun1和fun2都只是定义了,我们并没有去调用它两。那么问题来了,我们说作用域链其实就是函数的一个属性,是一个数组结构,我们也可以看一下,如下图
我们前面也说了,这个数组里面存的是变量对象,也就是代码执行前用于收集该环境下变量、函数、函数的参数、this。(找关键字var function)。但是此时我们的函数其实并没有调用,也就是说此时的函数并没有执行上下文,也没有自己的变量对象。那么这个函数的这个作用域链数组存放的是什么?
存放的是上一级的变量对象。在我们的函数被调用,要有执行上下文了,我们才会产生自己的作用域链,也就是会把现在被调用的函数的变量对象加入到这个函数的作用域链数组的最前面。
此时我就因为人比较笨,没想清楚为啥这个函数没执行里面会知道上级的变量对象呢?
后来要死要活才想清楚了,这样想。我们这个函数呢是在上级的作用域里面定义的,也可以说其实就是上级的变量对象里的一个函数变量。我们这个函数能够被定义,就说明了上级作用域里的代码是要执行的,那么上级作用域要执行,就会产生执行上下文还有变量对象,在函数定义的时候,函数里面的参数作用域数组里面就插入了上级的变量对象,实际上是把上级的作用域数组直接拷贝过来。
我们可以用这样一段代码去实践一下,定义了两个函数,一个是fun1一个是fun2,然后再fun2里调用了fun1;随后我们发现fun1的作用域数组还是window的变量对象global。