对js执行上下文的理解

2020-09-16  本文已影响0人  hello_小丁同学

执行上下文

执行上下文有三种:

  1. 全局执行上下文
    在执行全局代码的时候会创建全局上下文
  2. 函数执行上下文
    在执行函数代码的时候会创建函数执行上下文
  3. eval执行上下文
    eval执行的代码段也会创建一个执行上下文

执行上下文是通过栈进行管理的,在栈底部是全局执行上下文,当开始执行函数,函数的执行上下文就会被push到栈的顶部,执行结束就会被从栈顶弹出,也标志着函数生命周期的结束。

在执行一段js代码之前会先进入执行上下文(execution context),在这个阶段会对变量和函数进行处理,具体流程:

  1. 形式参数(formal parameter)
    会把函数所有的形参作为VO(Variable Object)的key,对应的value初始化为undefined
  2. 函数声明(FunctionDeclaration)
    会把所有函数名称作为VO的key,对应的value被赋给对应函数的地址。如果VO里面已经包含了这个key,会把新的value赋给这个key。
  3. 变量声明(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、执行阶段

  1. 创建阶段
    在执行到foo()的时候,先是进入创建阶段,函数会创建可执行上下文(execution content),同时会创建AO(Activation Object),并对AO进行初始化。
    创建阶段结束之后AO变成了
AO = {
cat: <cat函数的地址>
x: undefiend
}
  1. 代码执行阶段
    会对x进行赋值
AO = {
cat: <cat函数的地址>
x: 10
}

cat函数由于没有执行到,所以cat的AO没有被创建。

参考资料

上一篇下一篇

猜你喜欢

热点阅读