zoukankan      html  css  js  c++  java
  • 读《javascript核心技术揭秘》深入理解执行上下文

    执行上下文

    什么是执行上下文

    执行上下文非常重要,其中涉及了变量对象、作用域链、 this,闭包 等许多重要但并不那么容易搞清楚的概念,这些概念有助于我们真正理解 JavaScript 代码的运行机制,所以执行上下文牵扯的东西太多了,非常重要,非常重要,非常重要!!!

    JavaScript代码在执行时,会进入一个执行上下文中。执行上下文可以理解为当前代码的运行环境

    JavaScript中的运行环境主要包括以下三种情况:

    • 全局环境:代码运行起来后会首先进入全局环境

    • 函数环境:当函数被调用执行时,会进入当前函数中的执行代码

    • eval环境:不建议使用,不做介绍

    JavaScript引擎会以栈的方式处理这些环境,这个栈就是函数调用栈,函数调用栈规定了JavaScript代码的执行顺序。栈底永远是全局上下文,栈顶则是当前正在执行的上下文

    举个例子:

    var color = 'blue';
    
    function changeColor() {
      var anotherColor = 'red';
    
      function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
      }
    
      swapColors();
    }
    
    changeColor();
    

    我们用ECStack来表示处理执行上下文组的堆栈。我们很容易知道,第一步,首先是全局上下文入栈。

    全局上下文入栈之后,其中的可执行代码开始执行,直到遇到了changeColor(),这一句激活函数changeColor创建它自己的执行上下文,因此第二步就是changeColor的执行上下文入栈。

    changeColor的上下文入栈之后,控制器开始执行其中的可执行代码,遇到swapColors()之后又激活了一个执行上下文。因此第三步是swapColors的执行上下文入栈。

    在swapColors的可执行代码中,再没有遇到其他能生成执行上下文的情况,因此这段代码顺利执行完毕,swapColors的上下文从栈中弹出。

    swapColors的执行上下文弹出之后,继续执行changeColor的可执行代码,也没有再遇到其他执行上下文,顺利执行完毕之后弹出。这样,ECStack中就只剩下全局上下文了。

    全局上下文在浏览器窗口关闭后出栈。

    注意:函数中,遇到return能直接终止可执行代码的执行,因此会直接将当前上下文弹出栈。

    详细了解了这个过程之后,我们就可以对执行上下文总结一些结论了。

    • 单线程

    • 同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待

    • 全局上下文只有唯一的一个,它在浏览器关闭时出栈

    • 函数的执行上下文的个数没有限制

    • 每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此。

    根据函数执行时才会创建执行执行上下文这一原则去理解上下文

    上下文的生命周期

    我们知道,当一个函数调用时,一个新的执行上下文就会被创建,一个执行上下文的生命周期大致分为两个阶段:创建阶段和执行阶段

    创建阶段

    在这个阶段,执行上下文会分别创建变量对象确定作用域链以及this指向

    执行阶段

    创建阶段之后,就会开始执行代码,这个时候会完成变量赋值,函数引用,以及执行其它可执行代码,如图所示

    从执行上下文的生命周期可以看到它的重要性,其中涉及了变量对象、作用域链、this等许多重要但并不那么容易搞清楚的概念,这些概念有助于我们真正理解JavaScript代码的运行机制

    来个例子巩固一下上面所说的:

    function test() {
        console.log(a);
        console.log(foo());
        var a = 1;
        function foo() {
            return 2;
        }
    }
    
    test();
    

    当运行test函数,对应的上下文创建,可以采用如下形式来表达整个过程

    // 创建阶段
    testEC={
        VO:{}, // 变量对象
        scopeChain:[], // 作用域链
        this:{}
    }
    
    VO={
        arguments:{...},
        foo:<foo reference>,
        a:undefined
    }
    
    
    // 执行阶段
    VO -> AO
    VO = {
        arguments: {...},
        foo: 1,
        bar: <bar reference>,
        this: Window
    }
    
  • 相关阅读:
    . Embedding Python in Another Application¶
    hive wiki
    PC机与ARM板的聊天软件
    Hadoop hive 运行examples例子 andy030611的日志 网易博客
    Notes on Ubuntu (Linux) computing
    数据结构利器之私房STL(上)
    Embedding Python in C/C++: Part I CodeProject
    linux下dup2的实现
    单台服务器上安装Hadoop和Hive十五分钟教程
    Data Structures with C++ Using STL Chapter 3算法概述笔记
  • 原文地址:https://www.cnblogs.com/vnues/p/14300328.html
Copyright © 2011-2022 走看看