# JavaScript 运行时深度指南 ::: tip 前言 你已经学会了 JavaScript 的基本语法,但你是否想过: - 代码到底在哪里运行? - 为什么同样的代码在浏览器和 Node.js 中行为不一样? - 为什么有时代码会"卡住",有时却能"并行"执行? 这篇文章会带你深入了解 JavaScript 的运行时环境,包括事件循环、调用栈、内存管理等。读完这篇,你就能理解代码为什么按某个顺序执行,快速定位异步相关的 bug,优化代码性能并避免内存泄漏。 ::: **这篇文章会带你学什么?** | 章节 | 内容 | 学完能干嘛 | |-----|------|-----------| | **第 1 章** | 运行时概述 | 理解 JavaScript 代码在哪里运行 | | **第 2 章** | 浏览器运行时 | 知道浏览器提供了哪些 Web API | | **第 3 章** | Node.js 运行时 | 了解服务器端的 JavaScript 环境 | | **第 4 章** | 事件循环深入 | 掌握宏任务和微任务的执行顺序 | | **第 5 章** | 调用栈与内存 | 理解代码执行过程和内存管理 | | **第 6 章** | 实战技巧 | 优化性能、调试内存泄漏 | --- ## 1. 运行时概述 ::: tip 🤔 核心问题 **什么是"运行时"?** JavaScript 只是一门语言,为什么同样的代码在不同环境中会有不同的行为? ::: ### 1.1 运行时是什么 **运行时 = JavaScript 引擎 + 环境提供的 API** 如果把 JavaScript 比作"编程语言",那么运行时就是"操作系统"——它决定了你的代码能做什么、不能做什么。 ``` ┌─────────────────────────────────────┐ │ JavaScript 代码 │ ├─────────────────────────────────────┤ │ JavaScript 引擎 (V8) │ ← 负责解析和执行代码 ├─────────────────────────────────────┤ │ 运行时环境 (浏览器/Node.js) │ ← 提供额外能力 └─────────────────────────────────────┘ ``` **一个比喻:JavaScript 是"普通话",运行时是"城市"** - JavaScript 语法(普通话)哪里都一样 - 但不同城市提供的设施不一样: - 浏览器 = 有 DOM、window、fetch(就像城市有商场、图书馆) - Node.js = 有 fs、http、path(就像城市有工厂、高速公路) ### 1.2 两大主流运行时 | 特性 | 浏览器 | Node.js | |------|--------|---------| | **主要用途** | 网页交互、用户界面 | 服务器端应用、命令行工具 | | **全局对象** | `window` | `global` | | **DOM API** | ✅ 支持 | ❌ 不支持 | | **文件系统** | ❌ 受限 | ✅ 完整支持 | | **模块系统** | ES Modules | CommonJS + ES Modules | | **定时器** | `setTimeout`, `setInterval` | `setTimeout`, `setInterval` | | **网络请求** | `fetch`, `XMLHttpRequest` | `http`, `https` 模块 | 👇 **动手试试看**:对比浏览器和 Node.js 的环境差异 ::: info 💡 核心启示 运行时决定了你能用什么 API。在浏览器能用的 DOM API,在 Node.js 里用不了;在 Node.js 能用的文件 API,在浏览器里也用不了。这就是为什么有些代码需要"环境判断"。 ::: --- ## 2. 浏览器运行时 ::: tip 🤔 核心问题 **浏览器提供了哪些能力让 JavaScript 操作网页?** ::: ### 2.1 浏览器运行时的组成 ``` ┌─────────────────────────────────────────────┐ │ JavaScript 引擎 │ │ (V8 / SpiderMonkey) │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Web APIs │ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ │ │ DOM │ │ BOM │ │ Network │ │ │ │ 操作网页 │ │ 操作浏览器 │ │ 网络请求 │ │ │ └─────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 事件循环 (Event Loop) │ │ 负责协调代码执行、事件处理、任务调度 │ └─────────────────────────────────────────────┘ ``` ### 2.2 Web APIs 的三大类 **1. DOM API - 操作网页内容** ```javascript // 查找元素 const title = document.querySelector('h1') // 修改内容 title.textContent = '新标题' // 添加样式 title.style.color = 'red' ``` **2. BOM API - 操作浏览器** ```javascript // 页面跳转 window.location.href = 'https://example.com' // 浏览器存储 localStorage.setItem('key', 'value') // 浏览器历史 history.back() ``` **3. Network API - 网络请求** ```javascript // 发送 HTTP 请求 fetch('/api/data') .then(response => response.json()) .then(data => console.log(data)) ``` ### 2.3 浏览器特有的事件机制 浏览器运行时最强大的功能之一是"事件驱动"——代码不需要一直运行,而是等用户操作时才执行。 ```javascript button.addEventListener('click', () => { console.log('按钮被点击了') }) ``` **常见事件类型:** | 事件类型 | 触发时机 | 实际场景 | |---------|---------|---------| | `click` | 鼠标点击 | 按钮交互 | | `input` | 输入框内容变化 | 实时搜索 | | `scroll` | 页面滚动 | 懒加载 | | `load` | 资源加载完成 | 初始化数据 | | `error` | 发生错误 | 错误处理 | --- ## 3. Node.js 运行时 ::: tip 🤔 核心问题 **JavaScript 能在服务器端运行,靠的是什么?** ::: ### 3.1 Node.js 的组成 ``` ┌─────────────────────────────────────────────┐ │ JavaScript 引擎 │ │ (V8) │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Node.js 内置模块 │ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ │ │ fs │ │ http │ │ path │ │ │ │ 文件操作 │ │ 网络服务器 │ │ 路径处理 │ │ │ └─────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ libuv 事件循环库 │ │ 跨平台的异步 I/O 支持 │ └─────────────────────────────────────────────┘ ``` ### 3.2 Node.js 特有能力 **1. 文件系统操作** ```javascript const fs = require('fs') // 读取文件 fs.readFile('./data.txt', 'utf8', (err, data) => { if (err) throw err console.log(data) }) // 写入文件 fs.writeFile('./output.txt', 'Hello', (err) => { if (err) throw err console.log('写入成功') }) ``` **2. HTTP 服务器** ```javascript const http = require('http') const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }) res.end('

Hello World

') }) server.listen(3000) ``` **3. 模块系统** ```javascript // CommonJS (Node.js 默认) const fs = require('fs') module.exports = { myFunction } // ES Modules (现代方式) import fs from 'fs' export { myFunction } ``` ### 3.3 浏览器 vs Node.js 对比 | 特性 | 浏览器 | Node.js | |------|--------|---------| | **入口文件** | HTML 文件 | JavaScript 文件 | | **全局对象** | `window`, `document` | `global`, `process` | | **模块加载** | `