
在 Node.js 的 Express 应用中,模块级声明的变量(如 let box = 0)属于单例作用域,会在整个服务生命周期内持续存在,导致多次 HTTP 请求共享同一变量值,而非每次请求独立初始化。
在 node.js 的 express 应用中,模块级声明的变量(如 `let box = 0`)属于单例作用域,会在整个服务生命周期内持续存在,导致多次 http 请求共享同一变量值,而非每次请求独立初始化。
这是 Node.js 模块机制与服务端执行模型共同作用的结果:TypeScript/JavaScript 文件被 require 或 import 后,其顶层作用域(module scope)仅执行一次,所有导出的函数都运行在同一个闭包环境中。因此,let box = 0 并非“每次请求新建”,而是“服务启动时初始化一次”,后续每次调用 index() 都会操作这个全局(模块级)变量。
✅ 正确做法是将状态变量声明为函数局部变量,确保每次请求都有独立作用域:
import { Request, Response } from "express";
import axios from "axios";
import { parseString } from "xml2js";
export const index = (req: Request, res: Response) => {
let box = 0; // ✅ 局部变量:每次请求创建新实例
box++;
res.json({ value: box }); // 推荐使用 res.json() 替代 JSON.stringify + res.send()
};
⚠️ 注意事项:
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
- 不要误用 var 声明——虽有函数作用域,但易引发提升(hoisting)混淆;始终优先使用 const/let;
- 若需跨请求持久化状态(如计数器、会话数据),应使用外部存储(Redis、数据库)或 Express 中间件管理的 req.session,而非模块变量;
- TypeScript 编译后的 JS 模块仍遵循 CommonJS/ESM 规范,模块缓存(require.cache)机制会复用已加载模块,进一步强化了“全局变量不重置”的行为。
总结:Node.js 是单线程事件循环模型,但模块变量 ≠ 请求变量。牢记「请求状态必须局部化」原则,才能写出可预测、可扩展、无副作用的 Web 处理逻辑。










