前端架构系列初见

javascript执行上下文栈和作用域链

2020-06-19  本文已影响0人  羽晞yose

执行上下文栈

操作系统对进程占用的内存空间的管理方式有两种:堆和栈
栈:是一种先进后出模式,而执行上下文栈,从名称上也可以看出,它是一种后进先出的模式
执行上下文就是当前 JavaScript 代码被【解析】和【执行时】所在环境的抽象概念

执行上下文三种类型

  1. 全局执行上下文: 这是默认的、最基础的执行上下文。不在任何函数中的代码都位于全局执行上下文中。它做了两件事:1. 创建一个全局对象,在浏览器中这个全局对象就是 window 对象。2. 将 this 指针指向这个全局对象。一个程序中只能存在一个全局执行上下文。
  2. 函数执行上下文: 每次调用函数时,都会为该函数创建一个新的执行上下文。每个函数都拥有自己的执行上下文,但是只有在函数被调用的时候才会被创建。一个程序中可以存在任意数量的函数执行上下文。每当一个新的执行上下文被创建,它都会按照特定的顺序执行一系列步骤。
  3. Eval 函数执行上下文: 运行在 eval 函数中的代码也获得了自己的执行上下文

执行上下文的生命周期

创建阶段 -> 执行阶段 -> 回收阶段

图文并茂观察执行上下文栈的执行生命周期变化

先来一段代码

function a () {
    b();
}

function b () {
    c();
}

function c() {
    console.log('welcome');
}

debugger;
a();

通过控制台F11一步步调试


stack.gif

通过调试,观察控制台中的Call Stack可以看到下面一步步变化

  1. 还未执行,但此时栈中已有一个anonymous,也就是执行上下文
  2. 执行a(),此时上下文栈加入了a
  3. 执行b(),此时上下文栈加入了b
  4. 执行c(),此时上下文栈加入了c
  5. 执行完c(),此时上下文栈中移除c
  6. 执行完b(),此时上下文栈中移除b
  7. 执行完a(),此时上下文栈中移除a
  8. 程序执行完,只剩栈底anonymous,全局上下文只有在关闭浏览器窗口的时候才会被销毁

作用域链

作用域是在函数定义的时候就确定了。函数会保存一个内部属性[[scope]],这个变量会保存所有的父变量对象。查找的时候,会先在当前上下文变量对象中查找,如果找不到,就会向上级查找,一直找到所谓的全局对象。这个过程,查找多个变量对象所构成的链,则称为作用域链。

function a () {
    function b () {
        function c () {
            
        }
    }
}

a.[[scope]] = [
    globalContext.VO
]
b.[[scope]] = [
    aContext.AO,
    globalContext.VO
]
c.[[scope]] = [
    bContext.AO,
    aContext.AO,
    globalContext.VO
]

如果你看到这里了,那你肯定依旧一脸懵逼,因为这里是作为基础说明,并不会深入详解,有兴趣深入了解的请看新文章:全面攻克js中的堆栈内存及闭包

上一篇下一篇

猜你喜欢

热点阅读