全局对象与变量
Node.js 提供模块内可直接使用的全局对象;与浏览器 window 不同,模块顶层的 const/let 不会挂到 global。见 后端入门概览、模块系统。
1. global
- 作用:全局命名空间对象,类似于浏览器中的
window。在 Node.js 的 REPL 环境中或任意模块中,可以通过global访问全局作用域。 - 注意:在模块文件中,
var、let、const声明的变量不会成为global的属性,只属于模块局部作用域。如果想定义真正的全局变量,需显式赋值给global(通常不推荐,避免命名冲突)。
// 不会挂载到 global
var a = 1;
console.log(global.a); // undefined
// 显式挂载
global.b = 2;
console.log(global.b); // 2
Node.js 内置的一些全局 API 实际上是 global 的属性,例如 console、setTimeout。
2. __dirname
- 作用:返回当前模块文件所在的目录的绝对路径。
- 注意:在 ES 模块(使用
.mjs文件或"type": "module"的.js文件)中,__dirname不可用,需要通过import.meta.url手动构造。
// example.js 位于 /home/user/project/src
console.log(__dirname); // 输出: /home/user/project/src
ES 模块替代方案:
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
3. __filename
- 作用:返回当前模块文件的绝对路径(包含文件名和扩展名)。
- 注意:同样,ES 模块中不可直接使用,需通过
import.meta.url获取。
// /home/user/project/src/example.js
console.log(__filename);
// 输出: /home/user/project/src/example.js
4. module
- 作用:是一个指向当前模块的引用。每个 Node.js 文件都是一个模块,
module对象包含了该模块的元信息,如id、path、exports、parent、children等。 - 常见属性:
module.exports:模块导出的内容(核心)。module.id:模块标识符,通常是文件路径。module.loaded:模块是否加载完成。
console.log(module.id); // 模块的完整路径
console.log(module.paths); // 模块查找路径数组
5. exports
- 作用:
exports是module.exports的一个引用。通过它可以方便地导出模块内容。最终暴露给外部的是module.exports。 - 注意:直接对
exports赋值会切断与module.exports的联系,使导出失效。必须始终通过module.exports或exports.xxx添加属性。
// 正确用法
exports.foo = "bar";
module.exports.baz = "qux";
// 错误用法(会丢失导出)
exports = { foo: "bar" }; // 此时 exports 不再指向 module.exports
如果只需要导出一个函数或对象,推荐直接使用 module.exports = ...。
6. require
- 作用:用于加载其他模块的核心函数。参数可以是模块名、相对路径或绝对路径。
- 机制:
- 支持加载
.js、.json、.node(C++ 插件)文件。 - 加载 JSON 文件时会自动解析为对象。
- 具有缓存机制:多次
require同一个模块只会执行一次,返回相同的exports对象。 - 可以通过
require.resolve获取模块的完整路径,而不实际加载模块。
- 支持加载
const fs = require("fs"); // 加载内置模块
const myModule = require("./mod"); // 加载本地模块(可省略 .js)
const data = require("./data.json"); // 加载 JSON
查找规则:Node.js 会从当前文件目录开始,依次查找 node_modules 目录,直到文件系统根目录。
7. process
- 作用:提供当前 Node.js 进程的信息和控制能力。它是
EventEmitter的实例,可以监听进程事件。 - 常用属性与方法:
process.argv:命令行参数数组。process.env:环境变量对象。process.cwd():返回当前工作目录。process.exit(code):退出进程。process.on('uncaughtException', callback):捕获未处理的异常。process.nextTick(callback):将回调推迟到事件循环的下一个阶段执行(比setImmediate优先级高)。process.platform:操作系统平台(如'win32'、'linux')。process.version:Node.js 版本号。
// 打印所有环境变量
console.log(process.env);
// 监听退出事件
process.on("exit", code => {
console.log(`进程退出,退出码:${code}`);
});
// 使用 nextTick
process.nextTick(() => {
console.log("在事件循环当前阶段结束后执行");
});
8. Buffer
- 作用:用于处理二进制数据(如文件流、网络数据)。在 TCP 流或文件操作中,数据的传输通常以 Buffer 形式进行。
- 特点:
- Buffer 是 Node.js 全局类,无需
require。 - 在 ES6 引入
TypedArray之前,Buffer 是 Node.js 处理二进制的主要方式,现在它实现了Uint8Array接口。 - Buffer 的大小在创建时就固定,无法动态调整。
- Buffer 是 Node.js 全局类,无需
- 常用方法:
Buffer.from(array)/Buffer.from(string):从数组或字符串创建 Buffer。Buffer.alloc(size):创建指定大小的零填充 Buffer。buf.toString(encoding):将 Buffer 转换为字符串(默认'utf8')。buf.length:Buffer 的字节长度。
// 创建 Buffer
const buf1 = Buffer.from("Hello", "utf8");
console.log(buf1); // <Buffer 48 65 6c 6c 6f>
const buf2 = Buffer.alloc(5); // 长度为 5 的零填充 Buffer
buf2.write("Hi"); // 写入数据
// 合并两个 Buffer
const combined = Buffer.concat([buf1, buf2]);
console.log(combined.toString()); // "HelloHi"
注意:Node.js 中很多 API 既接受 string 也接受 Buffer,例如 fs.readFile 可以返回 Buffer。
相互关系与注意事项
exportsvsmodule.exports:初始化时exports和module.exports指向同一个对象。若只添加属性,两者皆可;若要导出对象本身,必须用module.exports。require的缓存:模块首次加载后会被缓存,因此模块内的全局变量不会重复初始化,但也意味着需要小心模块状态的共享。__dirname与__filename:在 CommonJS 模块中可用,在 ES 模块中需自行构造。process.nextTick:它在当前事件循环阶段结束时立即执行,优先级高于setImmediate和Promise微任务,但Promise的微任务会在nextTick之前执行(取决于 Node.js 版本,实际顺序:nextTick队列 > 微任务队列 > 其他阶段)。
参考文献
以下链接在编写时均可正常访问:
相关文章
事件循环
Node.js 的事件循环是其实现非阻塞 I/O 的核心机制。它基于 libuv 库,将各种异步操作(定时器、I/O、setImmediate 等)组织成不同的阶段,每个阶段都有一个先进先出的回调队列。事件循环会按照固定的顺序反复执行…
模块系统
Node.js 的模块系统是其核心设计之一,它允许开发者将代码拆分为多个文件(模块),通过 require(CommonJS)或 import/export(ESM)进行组织和复用。下面详细介绍 CommonJS、ESM 以及两者的互操作。
事件驱动与非阻塞 I/O 模型
Node.js 的底层架构核心是事件驱动与非阻塞 I/O:以 V8 引擎执行 JavaScript、libuv 库处理底层 I/O 与事件循环。涵盖 libuv 线程池、事件循环各阶段、EventEmitter 实践、最佳实践与常见坑。
后端入门概览
本目录覆盖 JavaScript/TypeScript 服务端运行时与框架、数据存储,以及 Rust 系统编程入门,提供从零到部署的完整学习路径。前置建议:JavaScript 基础、工程化 · 环境变量。
文件系统
Node.js 的 fs 模块提供了与文件系统交互的 API,几乎涵盖了所有标准文件操作。它支持三种风格的 API:同步、回调式异步 和 Promise 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。
异步编程与模式
Node.js 的核心优势在于异步非阻塞 I/O,但这也带来了回调地狱、错误处理复杂等问题。下面从解救方案、工具函数、并发控制、异步迭代以及常见反模式等角度展开。
Series
base
4 / 4