你的浏览器不支持canvas

Enjoy life!

javascript - 执行上下文

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

一、执行上下文(Execution Context)

1.1 什么是执行上下文

  • 执行上下文(Execution Context, EC )可以理解为 当前代码的执行环境,它会形成一个作用域。

1.2 堆栈

  • 活动的执行上下文组在逻辑上组成了一个堆栈。
  • 堆栈底部 永远是 全局上下文(Global Context
  • 堆栈顶部当前(活动的)执行上下文
  • 堆栈在 EC 类型进入和退出上下文时被修改 — 推入或弹出
  • 我们可以将执行上下文的堆栈看作一个数组:ECStack = []
  • 只要执行流进入 function,这个function就会被压入堆栈内。

1.3 EC 分类

  • EC分为两类:
  • 1.全局执行上下文(全局环境):
    • Javascript 代码运行时会先进入该环境。
    • 全局执行环境直到应用程序退出,保存在其中的所有变量和函数定义才会被销毁。
    • 全局代码不包括任何function体内的代码。
  • 堆栈:

relationship-map

  • 2.函数执行上下文(函数环境):
    • 当函数被调用时,会进入当前函数中执行代码。
    • 执行环境中的所有代码执行完毕后,改环境被销毁,保存在其中的所有变量和函数定义也会被销毁。
  • 堆栈:

relationship-map

1.4 EC的生命周期

  • EC的生命周期如下:

relationship-map

1.5 EC 实例1

  • 代码如下:
var color = 'blue';

function changeColor() {
    var anotherColor = 'red';

    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
    }

    swapColors();
}

changeColor();
  • 数组理解:
var ECStack = [];
ECStack[0] = changeColor;
ECStack[1] = swapColor;
ECStack[2] = globalContext;

// 实际上就是:
var ECStack = [changeColor, swapColor, globalContext];
  • 图示理解:

relationship-map


relationship-map

1.6 EC 实例2

  • 代码如下:
function f1 () {
  var n = 100;
  
  function f2 () {
    console.log(n);
  }
  
  return f2;
}

var result = f1();

result(); // 100
  • 图示理解:

relationship-map

  • 可从图上看到 f1 出栈后 result(即:f2)才入栈。
  • 原因:因为 f1 中的函数 f2f1 的可执行代码中并没有被调用执行,因此,执行 f1 时,f2 不会创建新的上下文, 直到 result执行时,才创建其上下文。

二、总结

  1. 只有 栈顶 的上下文处于执行阶段,其他上下文需等待执行。
  2. 全局上下文只有一个,它只有在浏览器关闭时出栈。
  3. 函数的执行上下文的个数没有限制。
  4. 只要有函数被调用,就会有新的执行上下文被创建,即使调用自身的函数也是如此。

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。