jejuin / Blog

我的博客:记录、总结、分享前端知识
MIT License
4 stars 0 forks source link

JavaScript 之执行上下文的生命周期 #12

Open jejuin opened 4 years ago

jejuin commented 4 years ago

执行上下文的生命周期

Image

执行上下文的生命周期包括两个阶段:

我们以下面这段代码为例,分析执行上下文的整个生命周期。(示例来源于参考文章

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope();
  1. 当开始执行上述代码时,会创建全局执行上下文;
    
    ECStack.push(global_EC);

ECStrict = [ global_EC ]

2. 初始化全局执行上下文(创建阶段);

global_EC = { VO:window, // current scope + scopes of all its parents // 这里将 scope 用 VO 表示,是因为在作用域中查找变量,其实就是从变量对象中查找,变量对象可以理解为作用域的实体 scope: [VO], this: window }

window = { // 内置全局属性和函数 ... , // 声明的全局变量和函数 checkscope: reference to function checkscope(){}, scope: undefined, }

3. 进入执行阶段,执行代码。当开始执行`checkscope`函数时,创建该函数的执行上下文。

ECStack.push(checkscope_EC);

ECStrict = [ global_EC, checkscope_EC ]

4. 初始化`checkscope`函数的执行上下文(创建阶段)。

checkscope_EC = { VO: { arguments: { length: 0 }, scope: undefined, f: reference to function f(){}, } // current scope + scopes of all its parents scope: [global_EC.VO, VO], // 非严格模式 this: window }

5. 进入执行阶段,执行代码。当开始执行` f `函数时,执行过程同上,创建并初始化` f `函数的执行上下文;

ECStack.push(f_EC);

ECStrict = [ global_EC, checkscope_EC, f_EC ]

f_EC = { VO: { arguments: { length: 0 } }, // current scope + scopes of all its parents scope: [global_EC.VO, checkscope_EC.VO, VO], // 非严格模式 this: window }

6. 当` f `函数执行完毕,其执行上下文出栈;

ECStack.pop();

ECStrict = [ global_EC, checkscope_EC ]

7. 当` checkscope`函数执行完毕,其执行上下文出栈;

ECStack.pop();

ECStrict = [ global_EC ]


8. 当关闭浏览器或者当前浏览器窗口,全局执行上下文才出栈。

**参考:**
> [JavaScript深入之执行上下文](https://github.com/mqyqingfeng/Blog/issues/8)