美文网首页不羁放纵爱前端让前端飞程序员
javascript 执行上下文系列总结

javascript 执行上下文系列总结

作者: 淘淘笙悦 | 来源:发表于2018-06-28 11:27 被阅读81次

我在文章《javascript 执行上下文》中介绍了 javascript 代码在执行时,会相应地创建对应执行上下文并将其入栈出栈的过程。

每个执行上下文会包含三个重要属性,分别是变量对象(Variable Object,VO)作用域链(Scope Chain)this 指向

而我在文章《javascript 变量对象》《javascript 作用域链》《javascript this 指向》中详细地描述了在代码执行过程中,随着执行上下文的创建和执行,这三个重要属性的变化过程,接下来我就一个例子结合前面四篇文章,详细地说明执行上下文的具体处理过程。

假设有一个 javascript 文件中包含如下代码

function fn1() {
    var a = 1;
    function fn2(b) {
        var c=3
    }
    
    fn2(2)
}

fn1();

我们依旧可以很容易地知道,上述代码在执行过程中,执行上下文栈的变化过程如下

/*伪代码*/
// 代码执行时最先进入全局环境,全局上下文被创建并入栈
ECStack.push(globalContext);
// fn1 被调用,fn1 函数上下文被创建并入栈
ECStack.push(<fn1> functionContext);
// fn1 中调用 fn2,fn2 函数上下文被创建并入栈
ECStack.push(<fn2> functionContext);
// fn2 执行完毕,fn2 函数上下文出栈
ECStack.pop();
// fn1 执行完毕,fn1 函数上下文出栈
ECStack.pop();
// 代码执行完毕,全局上下文出栈
ECStack.pop();

我们已经知道,执行上下文在创建阶段,会分别生成变量对象建立作用域链确定 this 指向。那么我们接下来就按照上述代码的流程,详细说明各个执行上下文中这三个重要属性的情况。

首先进入全局环境,全局上下文被创建并入栈

全局上下文被创建时,其执行上下文如下

globalContext={
    VO:globalObj
    Scope:[globalContext.VO]
    this:globalContext.VO
}
接着 fn1 被调用,fn1 函数上下文被创建并入栈

这里需要说明的是,在 fn1 函数上下文被创建之前,会有一个函数定义(声明)过程,这个过程发生在全局上下文创建阶段,在这个过程中,fn1.[[scope]] 会保存其上层作用域的变量对象,所以此时 fn1.[[scope]]=[globalContext.VO]。

在 fn1 函数上下文创建阶段,其执行上下文如下

fn1Context={
    VO:{
        Arguments:{
            length:0
        },
        fn2:<function fn2 reference>,
        a:undefined
    },
    Scope:[fn1Context.VO,globalContext.VO]
    this:globalContext.VO
}

在 fn1 函数上下文执行阶段,其执行上下文如下

fn1Context={
    VO:{
        Arguments:{
            length:0
        },
        fn2:<function fn2 reference>,
        a:1
    },
    Scope:[fn1Context.VO,globalContext.VO]
    this:globalContext.VO
}
然后在 fn1 中调用 fn2,fn2 函数上下文被创建并入栈

同理可知,在 fn1 函数上下文创建阶段,fn2.[[scope]]=[fn1Context.VO,globalContext.VO]。

所以在 fn2 函数上下文创建阶段,其执行上下文如下

fn2Context={
    VO:{
        Arguments:{
            0:2,
            length:0
        },
        b:2
        c:undefined
    },
    Scope:[fn2Context.VO,fn1Context.VO,globalContext.VO]
    this:globalContext.VO
}

在 fn2 函数上下文执行阶段,其执行上下文如下

fn2Context={
    VO:{
        Arguments:{
            0:2,
            length:0
        },
        b:2
        c:3
    },
    Scope:[fn2Context.VO,fn1Context.VO,globalContext.VO]
    this:globalContext.VO
}
最后是各个上下文出栈

在各个上下文出栈后,其对应的变量对象会被 javascript 中的自动垃圾收集机制回收。

而我们经常说闭包能够访问其所在环境的变量,其实是因为闭包能够阻止上述变量对象被回收的过程。

关于 javascript 执行上下文系列,暂时就写这么多,以后有更深入的感悟,会继续补充的吶。

但其实我还漏了一个很重要的知识点,就是上面说的闭包啦,闭包跟变量对象以及作用域链有着千丝万缕的关系,后续我将用单独一篇文章介绍闭包,嗯哼。

相关文章

  • javascript 执行上下文系列总结

    我在文章《javascript 执行上下文》中介绍了 javascript 代码在执行时,会相应地创建对应执行上下...

  • 执行上下文

    深入理解JavaScript执行上下文、函数堆栈、提升的概念 解密 JavaScript 执行上下文

  • javascript 执行上下文

    归纳总结一下执行上下文系列,其中包括了变量对象、作用域链和 this。本篇主要详细介绍执行上下文。 执行上下文(E...

  • js深度剖析 : 执行环境和作用域链

    执行上下文 execution context 又称执行上下文或者执行环境. 执行上下文是JavaScript中一...

  • JavaScript 执行

    JavaScript 执行 一段 JavaScript 经过编译会生成两部分:执行上下文,可执行代码。在执行上下文...

  • 精品技术贴汇总

    about 执行上下文 深入理解JavaScript执行上下文、函数堆栈、提升的概念 JavaScript深入之变...

  • 深入浅出执行上下文、词法环境、变量环境

    执行上下文的概念 执行上下文:javascript 代码解析和执行时所在的环境。 执行上下文的类型 执行上下文分为...

  • 2020年前端面试复习必读文章

    1. JavaScript 基础 1.1 执行上下文/作用域链/闭包 理解 JavaScript 中的执行上下文和...

  • 编写高效的javascript

    读书笔记 1.当执行javascript代码时,javascript引擎会创建一个执行上下文。执行上下文设定了代码...

  • 执行上下文

    [TOC] 1.执行上下文 1.什么是执行上下文? 简而言之,执行上下文是评估和执行 JavaScript 代码的...

网友评论

  • web前端05:@淘淘笙悦关注了
  • web前端05:写的很好,欢迎关注微信公众号:程序员大牛!
    淘淘笙悦:@web前端05 已关注,欢迎关注我的公众号「淘淘笙悦」 :relaxed:

本文标题:javascript 执行上下文系列总结

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