首先我们需要了解到浏览器事件循环的工作原理
浏览器事件循环是 JavaScript 运行时的一部分,用于管理 JavaScript 代码的执行顺序。浏览器事件循环主要由两个部分组成:执行栈和消息队列。
执行栈(Call Stack)是一个存储函数调用的栈结构。JavaScript 引擎会按照代码的顺序将函数调用压入执行栈中执行,直到执行栈为空。当遇到异步操作(如 setTimeout、事件监听器、Promise 等)时,JavaScript 引擎将其添加到消息队列中等待执行。
消息队列(Message Queue)是一个先进先出的队列结构,用于存储等待执行的消息。消息队列中的消息是异步操作完成后的回调函数,它们会在执行栈中的所有函数执行完毕后按照顺序依次添加到执行栈中执行。
因此,当全局作用域下的代码执行时,它们会被依次添加到执行栈中执行。如果代码中存在异步操作,则异步操作的回调函数会被添加到消息队列中等待执行。当执行栈中的所有函数执行完毕后,事件循环会检查消息队列中是否存在待执行的回调函数,如果存在则将其添加到执行栈中执行。
总之,JavaScript 的事件循环机制保证了 JavaScript 的单线程执行模型,通过将异步操作添加到消息队列中,从而实现异步执行。同时,由于消息队列是先进先出的结构,因此保证了回调函数的执行顺序。
定义变量也会被添加到执行栈中执行
当 JavaScript 引擎遇到变量声明语句(如 var、let、const)时,会将变量的声明添加到执行栈中,并为变量分配内存空间。此时变量的值为 undefined。
比如此时我需要定义一个变量:
let num = 10;
当上面这行代码执行时,JavaScript 引擎会将变量声明语句 var a 添加到执行栈中,并分配内存空间存储变量 a。接着,将 10 赋值给变量 a,完成赋值操作。
执行栈和栈内存是两个不同的概念
执行栈(Call Stack)是 JavaScript 引擎用来管理函数调用的栈结构。它会按照函数调用的顺序,将函数调用添加到栈中执行,并在函数执行完毕后弹出栈。执行栈的大小受到浏览器或者 Node.js 运行环境的限制,当执行栈超出一定大小时,会抛出栈溢出异常。
栈内存(Stack Memory)是指存储在栈中的数据,例如函数的局部变量和参数等。当函数调用时,会为其分配一段栈内存,函数执行完毕后会自动释放该内存。栈内存的大小通常比较有限,通常只有几百 KB 到几 MB,而且分配和释放内存非常快。
虽然执行栈和栈内存都是基于栈结构的概念,但是它们所管理的数据类型不同。执行栈主要用来管理函数调用,而栈内存则用来存储函数的局部变量和参数等。执行栈和栈内存都是 JavaScript 引擎的内部实现,开发者一般不需要直接操作它们。