理解 JavaScript 的执行上下文

  • JavaScript
  • 梁凤波
  • 336
  • 2

执行上下文

执行上下文指当前的执行环境中的,变量、函数声明,参数,作用域链和this等信息。

包含2个上下文:

  1. 全局执行上下文(只有一个)
  2. 函数执行上下文(每次调用函数都会创建一个新的上下文)

包含的3个重要属性:

  1. 变量对象(VO)
  2. 作用域链(Scope Chain)
  3. this
const ExecutionContext = {
    VO: window, // 变量对象
    ScopeChain: {}, // 作用域链
    this: window
};

执行上下文的生命周期

执行上下文的生命周期分为2个:创建和执行。

  • 创建阶段:
    • 创建变量对象
    • 建立作用域链
    • 确定 this 的指向
  • 执行阶段:
    • 变量的赋值
    • 函数的引用
    • 执行其他的代码
  • 执行完毕后,从上下文栈顶弹出,等待回收

执行上下文栈

JS引擎首先会创建一个执行上下文栈,作用是管理上下文。在JS解释器初始化时首先创建一个全局上下文且压入上下文栈顶中,随着遇到函数调用时,会创建一个新的函数执行上下文且压入到上下文栈顶中,随着函数执行完后,会被上下文栈顶弹出,直回到全局上下文。

var a = 10;

function fn2() {
    console.log('fn2');
}

function fn1() {
    fn2();
    console.log('fn1');
}

fn1();

// 模拟:创建一个上下文栈
let ECStack = [];

// 首先是创建了一个全局上下文压到上下文栈顶中
ECStack.push('globalContext'); // => ['globalContext']

// 然后遇到了fn1函数调用,创建fn1的上下文,且把fn1压入上下文栈顶中
ECStack.push("fn1Context"); // => ['globalContext', 'fn1Context']

// fn1里面也执行了fn2的函数,由此创建了f2的上下文,且把fn2上下文压入上下文栈顶中
ECStack.push("fn2Context"); // => ['globalContext', 'fn1Context', 'fn2Context']

// 执行完fn2函数后,fn2上下文从栈顶弹出
ECStack.pop(); // 弹出fn2Context => ['globalContext', 'fn1Context']

// fn2弹出后,回到了fn1函数执行完后,fn1上下文从栈顶弹出
ECStack.pop(); // 弹出fn1Context => ['globalContext']

console.log(ECStack); // ['globalContext']
// 最后,ECStack底层一直存在着全局上下文 globalContext
欢迎评论
评论列表
avatar

tian

hahahah

avatar

8ee

ee

TOP