Chrome DevTools调试Node.js时函数语句的异常引用行为
问题原因与解决方案
嘿,这个问题我之前调试Node.js的时候也踩过类似的坑,本质是模块作用域和调试控制台执行上下文的差异在搞鬼,给你拆解清楚:
为什么会出现这种矛盾?
你的脚本是作为Node.js模块运行的,Node.js的每个模块都有自己的私有作用域:
- 脚本里的
function f(){}; f=1;都属于这个模块的私有作用域,不会自动挂载到全局对象(global)上。 - 脚本内部的
console.log(f)能输出1,是因为它就在模块作用域里执行,自然能访问到这个变量。 - 但Chrome DevTools的调试控制台,默认是在全局作用域下执行代码的。当你输入
f时,它会去global对象里找这个变量,而模块里的f根本不在全局作用域,所以就抛出了Uncaught ReferenceError: f is not defined。
怎么在调试控制台访问到f?
给你几个实用的解决办法:
- 方法1:用断点切换作用域
在脚本里加一行debugger;(比如放在console.log(f);后面),重新启动调试。当代码停在断点时,调试控制台的执行上下文会自动切换到模块作用域,这时候你输入f就能拿到1了。
修改后的代码示例:function f(){}; f=1; console.log(f); debugger; http = require('http'); myserver=http.createServer(function (req, res) { res.end(); }).listen(8080); - 方法2:显式挂载到全局
如果你希望变量在全局作用域也能直接访问,可以把赋值语句改成:
这样调试控制台直接输入function f(){}; global.f = 1; console.log(f);f就能拿到正确的值了。 - 方法3:通过模块对象访问
如果你不想改动代码,也可以在调试控制台里输入module.exports.f(前提是你没有修改过module.exports的指向),这样也能获取到模块作用域里的f变量。
内容的提问来源于stack exchange,提问作者Grigory Hatsevich
相关产品推荐
相关产品推荐

