JS 执行上下文与执行栈

169 阅读2分钟

提示

本文全篇会将执行上下文简称为“上下文”。

什么是上下文

所有的JavaScript代码在运行时都是在上下文中进行的。那么,上下文是什么呢?简单来说,它就是当前JavaScript代码被解析和执行时所在环境的抽象概念。

上下文分类

  1. 全局上下文:最外层的上下文,也是最基础的上下文。根据ECMAScript实现的宿主环境,表示全局上下文的对象可能不一样。在浏览器中,它就是我们常说的window对象。一个程序中只能存在一个全局上下文。

  2. 函数上下文:每个函数都拥有自己的上下文。但只有在被调用时,才会被创建。一个程序中可以存在多个函数上下文。

  3. eval函数上下文:eval,大家都懂的,这是个毒瘤,千万不要在代码中使用,这里知道它就行,就不详细讨论了。

执行栈

执行栈(也叫调用栈或上下文栈),用于存储在代码执行期间创建的所有上下文。它是LIFO(Last in, First out,后进先出)结构。

当JavaScript引擎首次读取脚本时,会创建一个全局上下文并将其推到当前执行栈中。当代码执行流进入函数即函数被调用时,引擎会为该函数创建一个上下文并推到当前执行栈的栈顶,在函数执行完之后,执行栈会弹出该函数的上下文,将控制权返还给之前的上下文。ECMAScript程序的执行流就是通过这个执行栈进行控制的。

全局上下文,在浏览器关闭时出栈。

只通过文字描述,可能不够清晰明了。下面,我门一起看个例子:

function dog() {
    console.log('小狗汪汪叫');
    cat();
    function cat() {
        console.log('小猫喵喵叫');
    }
}
dog();

以上面代码为例,利用Chrome浏览器的开发者工具对其进行调试。大家要注意Call Stack(调用栈)的变化,它清楚地展示出上下文入栈出栈的过程。

May-30-2021 13-50-33.gif

为了更加方便理解,我将上述案例的上下文入栈出栈的过程,描绘成一个流程图,以供参考。

执行栈.png

结束语

关于执行栈和执行上下文,本文可能说得不是很详细。同时,同学们发现说的不对的地方,还请不吝赐教。最后,希望这篇文章能够对同学们有所帮助。biobio...