JavaScript 的执行过程涉及多个关键步骤,从代码加载到最终渲染或事件处理,其核心机制围绕 引擎解析、执行上下文管理、事件循环调度 展开。JavaScript 程序首先由引擎解析,浏览器或 Node.js 加载脚本后,进行词法分析和语法分析,检查语法错误。随后创建全局执行上下文,初始化变量环境和词法环境同步代码按顺序执行,异步任务则被推入任务队列等待调度。
一、javascript的执行步骤是什么?
代码加载与解析
浏览器环境:HTML 解析时遇到 <script> 标签,会暂停 DOM 构建,立即下载并解析 JS 文件。
Node.js 环境:直接读取文件内容,进入解析阶段。
解析过程:
词法分析:将代码拆分为 Token。
语法分析:生成 抽象语法树(AST),检查语法错误。
编译:V8 等引擎将 AST 转换为字节码。
执行上下文(Execution Context)创建
全局上下文:代码首次运行时创建,包含全局变量、this 绑定。
函数上下文:函数调用时创建,包含参数、局部变量、this。
词法环境(Lexical Environment):存储变量声明和函数定义,形成作用域链。
变量环境(Variable Environment):仅存储 var 变量,存在变量提升。
变量提升与初始化
var 变量:在编译阶段被提升到作用域顶部,初始值为 undefined。
函数声明:整体提升。
let/const 变量:存在“暂时性死区”(TDZ),在声明前访问会报错(ReferenceError)。
示例:
javascriptconsole.log(a); // undefined(var 提升)console.log(b); // ReferenceError(let 未初始化)var a = 1;let b = 2;
代码逐行执行
同步代码:按顺序执行,遇到表达式则计算值,遇到赋值则更新变量。
异步代码:
宏任务(Macrotask):如 setTimeout、setInterval、I/O 操作,由事件队列管理。
微任务(Microtask):如 Promise.then、MutationObserver,优先级高于宏任务。
执行顺序:同步代码 → 微任务队列 → 宏任务队列。
事件循环(Event Loop)调度
调用栈(Call Stack):存储当前执行的函数调用链,栈顶函数执行完毕后弹出。
任务队列:
微任务队列:当前调用栈清空后立即执行。
宏任务队列:微任务执行完毕后,从队列中取出下一个任务执行。
示例:
javascriptsetTimeout(() => console.log("Timeout"), 0);Promise.resolve().then(() => console.log("Promise"));console.log("Sync");// 输出顺序:Sync → Promise → Timeout
二、JavaScript 如何运行程序?
浏览器中的运行流程
HTML 解析:构建 DOM 树,遇到 <script> 时暂停解析,加载 JS 文件。
JS 执行:解析代码 → 创建全局上下文 → 执行同步代码 → 渲染引擎等待 JS 完成。
异步优化:
使用 defer 或 async 属性加载脚本,避免阻塞 DOM 构建。
通过 requestAnimationFrame 优化动画性能。
Node.js 中的运行流程
事件驱动架构:基于 libuv 库处理 I/O 操作,通过事件循环调度非阻塞任务。
模块系统:使用 CommonJS或 ES Modules管理代码依赖。
示例:
javascriptconst fs = require("fs");fs.readFile("file.txt", "utf8", (err, data) => {console.log(data); // 异步读取文件});
关键机制总结
单线程与异步:JS 引擎本身是单线程的,但通过事件循环和任务队列实现并发。
非阻塞 I/O:通过回调、Promise、Async/Await 避免耗时操作阻塞主线程。
作用域与闭包:函数执行时捕获当前词法环境,形成闭包。
三、示例:完整执行流程
javascriptconsole.log("Start"); // 同步代码 1setTimeout(() => console.log("Timeout"), 0); // 宏任务Promise.resolve().then(() => {console.log("Promise 1");setTimeout(() => console.log("Nested Timeout"), 0); // 嵌套宏任务});Promise.resolve().then(() => console.log("Promise 2")); // 微任务console.log("End"); // 同步代码 2// 输出顺序:// Start → End → Promise 1 → Promise 2 → Timeout → Nested Timeout
四、总结
JavaScript 的执行遵循 “解析 → 上下文创建 → 同步执行 → 异步调度” 的流程,核心依赖 执行上下文、作用域链、事件循环 三大机制。理解这些步骤能帮助你:
调试变量作用域问题。
优化异步代码性能。
合理设计模块化架构。
引擎通过调用栈管理函数执行,同步代码直接运行,遇到异步操作时,宏任务进入宏任务队列,微任务进入微任务队列。当前调用栈清空后,先执行所有微任务,再从宏任务队列中取出一个任务执行,如此循环形成事件循环。这一机制保证了单线程下的非阻塞运行,同时通过作用域链和闭包管理变量生命周期。