聊一聊JS的执行上下文
发布日期:2021-05-14 16:32:34 浏览次数:14 分类:精选文章

本文共 1699 字,大约阅读时间需要 5 分钟。

JS的执行上下文栈

JS的执行上下文是JS运行的核心机制之一。在开发过程中,理解JS的执行上下文栈是非常重要的,能够帮助我们更好地调试和优化代码。此外,了解执行上下文栈的相关知识,可以帮助我们更好地理解JS的执行机制。

全局执行上下文

当JS引擎开始运行时,会首先创建一个全局执行上下文。这个全局上下文会一直存在于执行上下文栈中,直到整个程序结束。因此,在任何时候ECStack中至少有一个全局上下文。

函数执行上下文

当JS引擎遇到函数代码块时,就会创建一个函数执行上下文,并将其压入执行上下下文栈中。随着函数的调用,执行上下文栈会不断被修改,函数的上下文会被压栈,而执行完成之后又会被弹栈。

执行上下文栈的管理

  • 栈结构:执行上下文栈是一个先进后出的数据结构,可以用数组来模拟。
  • 全局上下文:当整个程序运行时,ECStack中始终保留全局上下文。
  • 函数调用的压栈:每当一个函数被调用时,会创建一个对应的执行上下文并压栈。
  • 函数执行后的弹栈:只要函数完成执行,就会弹栈对应的执行上下文,确保栈结构的正确性。
  • 一个简单的示例

    function fun3() {
    console.log('fun3');
    }
    function fun2() {
    fun3();
    }
    function fun1() {
    fun2();
    }
    fun1();

    fun1()被调用时,执行上下文栈会经历以下变化:

  • fun1()被压栈,ECStack变为 [globalContext, fun1Context]
  • fun2()被调用,创建fun2Context并压栈,ECStack变为 [globalContext, fun1Context, fun2Context]
  • fun3()被调用,创建fun3Context并压栈,ECStack变为 [globalContext, fun1Context, fun2Context, fun3Context]
  • console.log('fun3')执行后,fun3Context弹栈,ECStack变为 [globalContext, fun1Context, fun2Context]
  • fun2()执行完成,fun2Context弹栈,ECStack变为 [globalContext, fun1Context]
  • fun1()执行完成,fun1Context弹栈,ECStack恢复为 [globalContext]
  • 执行上下文栈与变量提升

    JS引擎在解析代码时,遵循变量提升规则,函数声明提升、变量声明提升都会影响执行上下文栈。此外,在函数调用的过程中,当前执行上下文与之前函数定义的上下文会形成独立的执行环境。

    小练习

    var scope = "global scope";
    function checkscope() {
    var scope = "local scope";
    function f() {
    return scope;
    }
    return f;
    }
    checkscope();

    在这个代码中,执行上下文栈的变化如下:

  • 全局上下文被压栈,ECStack为 [globalContext]
  • �ーンcheckscope被调用,创建checkscopeContext并压栈,ECStack变为 [globalContext, checkscopeContext]
  • f()被定义并返回,创建fContext并压栈,ECStack变为 [globalContext, checkscopeContext, fContext]
  • f()被执行后,fContext弹栈,ECStack变为 [globalContext, checkscopeContext]
  • checkscope执行完成,checkscopeContext弹栈,ECStack恢复为 [globalContext]
  • 通过这组演示,我们可以清楚地看到,执行上下文栈为JS代码的执行提供了一个清晰的管理机制,使得复杂的函数调用和变量提升规则能够被有序执行。

    上一篇:深入理解JS的变量声明提升和函数声明提升
    下一篇:前端每日一题(一)

    发表评论

    最新留言

    路过按个爪印,很不错,赞一个!
    [***.219.124.196]2025年04月29日 23时27分16秒