执行上下文详细图解 - 图1

    我们在 JS 学习初期或者面试的时候常常会遇到考核变量提升的思考题。比如先来一个简单一点的。

    1. console.log(a);
    2. var a = 20;

    暂时先不管这个例子,我们先引入一个 JavaScript 中最基础,但同时也是最重要的一个概念执行上下文(Execution Context)。

    每次当控制器转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript 中的运行环境大概包括三种情况。

    1. 全局环境:JavaScript 代码运行起来会首先进入该环境

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

    3.eval

    因此在一个 JavaScript 程序中,必定会产生多个执行上下文,在我的上一篇文章中也有提到,JavaScript 引擎会以堆栈的方式来处理它们。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。

    当代码在执行过程中,遇到以上三种情况,都会生成一个执行上下文,放入栈中,而处于栈顶的上下文执行完毕之后,就会自动出栈。为了更加清晰的理解这个过程,根据下面的例子,结合图示给大家展示。

    1. var color = 'blue';
    2. function changeColor() {
    3. var anotherColor = 'red';
    4. function swapColors() {
    5. var tempColor = anotherColor;
    6. anotherColor = color;
    7. color = tempColor;
    8. }
    9. swapColors();
    10. }
    11. changeColor();

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

    执行上下文详细图解 - 图2

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

    执行上下文详细图解 - 图3

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

    执行上下文详细图解 - 图4

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

    执行上下文详细图解 - 图5

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

    执行上下文详细图解 - 图6

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

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

    执行上下文详细图解 - 图7

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

    1. 单线程

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

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

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

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

    为了巩固一下执行上下文的理解,我们再来绘制一个例子的演变过程,这是一个简单的闭包例子。

    1. function f1(){
    2. var n=999;
    3. function f2(){
    4. alert(n);
    5. }
    6. return f2;
    7. }
    8. var result=f1();
    9. result();

    因为 f1 中的函数 f2 在 f1 的可执行代码中,并没有被调用执行,因此执行 f1 时,f2 不会创建新的上下文,而直到 result 执行时,才创建了一个新的。具体演变过程如下。

    执行上下文详细图解 - 图8

    本文原创发布 php 中文网,转载请注明出处,感谢您的尊重!
    http://m.php.cn/article/351911.html