对js执行上下文的理解
2020-09-16 本文已影响0人
hello_小丁同学
执行上下文
执行上下文有三种:
- 全局执行上下文
在执行全局代码的时候会创建全局上下文 - 函数执行上下文
在执行函数代码的时候会创建函数执行上下文 - eval执行上下文
eval执行的代码段也会创建一个执行上下文
执行上下文是通过栈进行管理的,在栈底部是全局执行上下文,当开始执行函数,函数的执行上下文就会被push到栈的顶部,执行结束就会被从栈顶弹出,也标志着函数生命周期的结束。
在执行一段js代码之前会先进入执行上下文(execution context),在这个阶段会对变量和函数进行处理,具体流程:
- 形式参数(formal parameter)
会把函数所有的形参作为VO(Variable Object)的key,对应的value初始化为undefined - 函数声明(FunctionDeclaration)
会把所有函数名称作为VO的key,对应的value被赋给对应函数的地址。如果VO里面已经包含了这个key,会把新的value赋给这个key。 - 变量声明(VariableDeclaration)
会把所有的变量作为VO的key,对应的value初始化为undefined。如果变量名跟形参和函数名重复,不会对其覆盖。
上面的处理过程也解释了变量提升的原理。
VO和AO
VO(Variable Object)是执行上下文的一个属性,会存储形参、函数声明、和变量。
AO(Activation Object)在进入函数执行上下文中VO是不可被访问的,AO就承担了VO的角色。
函数的执行
function foo() {
var x = 10
function cat() {
x++
console.log(x)
}
}
foo()
详细看下上面代码怎么执行的,函数执行分为两个阶段:1、创建阶段 2、执行阶段
- 创建阶段
在执行到foo()的时候,先是进入创建阶段,函数会创建可执行上下文(execution content),同时会创建AO(Activation Object),并对AO进行初始化。
创建阶段结束之后AO变成了
AO = {
cat: <cat函数的地址>
x: undefiend
}
- 代码执行阶段
会对x进行赋值
AO = {
cat: <cat函数的地址>
x: 10
}
cat函数由于没有执行到,所以cat的AO没有被创建。
参考资料