美文网首页前端架构系列初见
javascript执行上下文栈和作用域链

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

作者: 羽晞yose | 来源:发表于2020-06-19 10:47 被阅读0次

    执行上下文栈

    操作系统对进程占用的内存空间的管理方式有两种:堆和栈
    栈:是一种先进后出模式,而执行上下文栈,从名称上也可以看出,它是一种后进先出的模式
    执行上下文就是当前 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中的堆栈内存及闭包

    相关文章

      网友评论

        本文标题:javascript执行上下文栈和作用域链

        本文链接:https://www.haomeiwen.com/subject/wfdhxktx.html