Node.js中IIFE与作用域运行逻辑及变量访问相关疑问
(async () => { const app = express(); let test = "test string"; app.get('/numbers', (req, res) => { res.send(test); }) // 原代码缺失该右括号,补充后可正常运行 app.listen( 8000, () => { console.log( `server running http://localhost:8000`); }); })();
代码运行逻辑
- 这段代码外层是一个立即执行的异步函数表达式(IIFE),脚本加载完成后会立刻触发执行
- 第一步初始化Express实例,赋值给变量
app - 第二步在IIFE作用域内声明变量
test,赋值为字符串test string - 第三步给Express实例注册GET请求路由
/numbers,绑定对应的请求处理回调函数 - 第四步调用
app.listen启动HTTP服务,监听本地8000端口,服务启动成功后触发回调打印启动日志 - IIFE内的同步代码执行完成后,因为HTTP服务处于持续运行状态,会持有Node.js事件循环的活跃引用,整个进程不会退出,会持续处理传入请求。
为什么GET路由的回调可以访问test变量
这是JS的闭包特性决定的:
函数的词法作用域在定义时就已经确定,内部定义的函数始终可以访问其外层词法作用域内的所有变量,和内部函数什么时候执行、在哪里执行无关。
你给/numbers路由注册的回调函数,是定义在IIFE内部的子函数,它的作用域链天然包含IIFE的作用域,所以哪怕这个回调是在IIFE执行完毕后、收到请求时才触发运行,依然有权限访问IIFE作用域内的test、app等变量。
IIFE执行完成后test变量为什么不会被销毁
JS的垃圾回收机制只会回收没有任何活跃引用的变量:
- 这里
test变量被/numbers的请求回调持续引用 - 该请求回调被Express实例
app持有 app因为启动的HTTP服务处于运行状态,一直持有活跃引用不会被回收
整个引用链全是存活状态,所以test变量不会被垃圾回收销毁,会一直保留在内存中,直到服务进程停止。
补充说明:你贴的原始代码存在语法错误,app.get定义结束后缺少一个右括号,补充后代码才可正常运行。
内容的提问来源于stack exchange,提问作者Ankit Arora
相关产品推荐
相关产品推荐

