# 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` |
| **模块加载** | `