js执行栈

109 阅读3分钟

JavaScript 中的执行栈(Execution Stack 或 Call Stack)是一种数据结构,用于管理代码执行过程中的函数调用与返回。它遵循后进先出(Last In, First Out, LIFO)原则,类似于栈数据结构,因此得名。执行栈在JavaScript引擎内部维护,负责跟踪并控制当前正在执行以及待执行的函数调用序列。以下是执行栈的关键特性及作用:

  1. 全局执行上下文:

    • 当JavaScript程序开始执行时,首先会创建一个全局执行上下文,并将其推入执行栈的底部。
    • 全局执行上下文中包含全局变量、函数声明以及其他预初始化的环境信息。
  2. 函数调用与执行上下文创建:

    • 当代码中遇到函数调用时,JavaScript引擎会为该函数创建一个新的执行上下文,并将其压入执行栈的顶部。
    • 函数执行上下文包含了函数局部变量、形参、函数内部的函数声明与变量声明、this值等运行时所需的信息。
  3. LIFO执行顺序:

    • JavaScript是单线程执行的,这意味着同一时刻只有一个函数可以处于执行状态。
    • 执行栈遵循LIFO原则:引擎始终从栈顶取出最上面的执行上下文进行执行。当一个函数执行完毕(即到达其结尾或通过return语句返回),对应的执行上下文就会从栈顶弹出(出栈),控制权返回给前一个执行上下文(通常是调用该函数的上下文)。
  4. 错误处理与堆栈追踪:

    • 如果在执行过程中发生未捕获的错误,JavaScript引擎会中断执行并生成一个错误对象,其中包含了错误信息和堆栈追踪信息。
    • 堆栈追踪反映了执行栈在错误发生时的状态,包括各个执行上下文的层级关系以及对应的代码位置,这对于调试非常有用,可以帮助开发者定位问题发生的具体函数调用链路。
  5. 与事件循环和任务队列的关系:

    • 执行栈与异步编程模型密切相关,但并不直接处理异步操作(如Promise、setTimeout、fetch等)。
    • 异步任务在特定条件满足后,其回调函数会被添加到事件循环的任务队列(如宏任务队列或微任务队列)中等待执行。
    • 当执行栈为空时(即当前没有正在执行的函数),事件循环会从任务队列中取出下一个任务(按照特定优先级规则),将其对应的回调函数的执行上下文压入执行栈,从而继续执行异步操作的结果处理。

总结来说,JavaScript执行栈是一种用于管理和调度函数调用、确保代码按序执行的核心机制。它以栈的形式组织执行上下文,确保了函数调用的有序性和内存的有效管理,是理解JavaScript单线程执行模型、函数调用过程以及异步编程行为的基础。