Javascript执行上下文栈

先入后出,后入先出
顶端push(放入) pop(输出)

JavaScript 代码执行顺序?

一段一段地分析执行
如何分段?
三种:全局代码、函数代码、eval代码

  • 执行一段代码的时候,会进行一个“准备工作”(即“执行上下文”),比如变量提升,函数提升。

    如何管理创建的那么多执行上下文呢?

    执行上下文栈(Execution context stack,ECS)来管理执行上下文
    执行一个函数时,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。

    执行上下文的三个属性

  • 变量对象
  • 作用域链
  • this

    变量对象 (VO)

    存储下列内容:
    变量
    函数声明
    函数的形参

    全局上下文的变量对象

    -> 全局对象
    全局对象就是 Window 对象 是由 Object 构造函数实例化的一个对象 是预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符
    通过使用全局对象,可以访问所有其他所有预定义的对象、函数和属性。

    函数上下文的变量对象

    -> 活动对象 (AO)
    在进入函数上下文时刻被创建,通过函数的 arguments 属性初始化

    作用域链

    当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象
    这样由多个执行上下文的变量对象构成的链表就叫做作用域链

    函数的创建

    函数有一个内部属性 [[scope]],当函数创建时,就会保存所有父变量对象到其中
    [[scope]] 就是所有父变量对象的层级链,但是注意:[[scope]] 并不代表完整的作用域链!

    函数的激活

    当函数激活时,进入函数上下文,创建 VO/AO 后,就会将活动对象添加到作用链的前端

    执行过程

    1.checkscope 函数被创建,保存作用域链到 内部属性[[scope]]
    2.执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈
    3.checkscope 函数并不立刻执行,开始做准备工作,第一步:复制函数[[scope]]属性创建作用域链
    4.第二步:用 arguments 创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明
    5.第三步:将活动对象压入 checkscope 作用域链顶端
    6.准备工作做完,开始执行函数,随着函数的执行,修改 AO 的属性值
    7.查找到 scope2 的值,返回后函数执行完毕,函数上下文从执行上下文栈中弹出
分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理